diff --git a/audio/skill/twjuezhu1.mp3 b/audio/skill/twjuezhu1.mp3 new file mode 100644 index 000000000..b48a5444d Binary files /dev/null and b/audio/skill/twjuezhu1.mp3 differ diff --git a/audio/skill/twjuezhu2.mp3 b/audio/skill/twjuezhu2.mp3 new file mode 100644 index 000000000..15bf778ed Binary files /dev/null and b/audio/skill/twjuezhu2.mp3 differ diff --git a/character/clan.js b/character/clan.js index 5bbf5af8f..c26fcf4fc 100644 --- a/character/clan.js +++ b/character/clan.js @@ -16,16 +16,264 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 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:太原王氏']], }, characterSort:{ clan:{ clan_wu:['clan_wuxian','clan_wuban','clan_wukuang'], clan_xun:['clan_xunshu','clan_xunchen','clan_xuncai','clan_xuncan'], clan_han:['clan_hanshao','clan_hanrong'], - clan_wang:['clan_wangling'], + clan_wang:['clan_wangling','clan_wangyun'], + clan_zhong:['clan_zhongyan'], }, }, skill:{ + //族王允 + clanjiexuan:{ + audio:2, + enable:'phaseUse', + limited:true, + zhuanhuanji:'number', + mark:true, + marktext:'☯', + intro:{ + markcount:()=>0, + content:function(storage){ + return '限定技,转换技。你可以将一张'+((storage||0)%2?'黑色牌当【过河拆桥】':'红色牌当【顺手牵羊】')+'使用。'; + }, + }, + viewAs:function(cards,player){ + var storage=player.storage.clanjiexuan; + var name=(storage||0)%2?'guohe':'shunshou'; + return {name:name}; + }, + check:function(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:function(card,player){ + var storage=player.storage.clanjiexuan; + return get.color(card)==((storage||0)%2?'black':'red'); + }, + skillAnimation:true, + animationColor:'thunder', + precontent:function(){ + 'step 0' + var skill='clanjiexuan'; + player.logSkill(skill); + player.changeZhuanhuanji(skill); + player.awakenSkill(skill,true); + delete event.result.skill; + }, + ai:{ + order:function(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:{ + audio:2, + enable:'phaseUse', + limited:true, + filterTarget:true, + skillAnimation:true, + animationColor:'thunder', + content:function(){ + 'step 0' + player.awakenSkill('clanmingjie'); + player.addSkill('clanmingjie_effect'); + player.markAuto('clanmingjie_effect',[target]); + target.addTempSkill('clanmingjie_targeted',{player:'phaseAfter'}); + target.markAuto('clanmingjie_targeted',[player]); + }, + ai:{ + order:10, + result:{ + target:function(player,target){ + if(player.getStorage('clanmingjie_effect').contains(target)) return 0; + 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; + } + 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); + }, + } + }, + subSkill:{ + effect:{ + trigger:{player:'useCard2'}, + charlotte:true, + filter:function(event,player){ + var card=event.card; + var info=get.info(card); + if(info.allowMultiple==false) return false; + if(event.targets&&!info.multitarget){ + if(player.getStorage('clanmingjie_effect').some(current=>{ + return current.isIn()&&!event.targets.contains(current)&&lib.filter.targetEnabled2(card,player,current); + })){ + return true; + } + } + return false; + }, + prompt:'是否发动【铭戒】?', + prompt2:function(event,player){ + var list=player.getStorage('clanmingjie_effect').filter(target=>{ + if(event.targets.contains(target)||!target.isIn()) return false; + return lib.filter.targetEnabled2(event.card,player,target); + }); + return '令'+get.translation(list)+'也成为'+get.translation(event.card)+'的目标'; + }, + logTarget:function(event,player){ + return player.getStorage('clanmingjie_effect').filter(target=>{ + if(event.targets.contains(target)||!target.isIn()) return false; + return lib.filter.targetEnabled2(event.card,player,target); + }); + }, + check:function(event,player){ + var eff=0; + var list=player.getStorage('clanmingjie_effect').filter(target=>{ + if(event.targets.contains(target)||!target.isIn()) return false; + return lib.filter.targetEnabled2(event.card,player,target); + }); + for(var i of list) eff+=get.effect(i,event.card,player,player); + return eff>0; + }, + content:function(){ + var list=player.getStorage('clanmingjie_effect').filter(target=>{ + if(trigger.targets.contains(target)||!target.isIn()) return false; + return lib.filter.targetEnabled2(trigger.card,player,target); + }); + if(list.length>0){ + trigger.targets.addArray(list); + game.log(list,'也成为了',trigger.card,'的目标'); + } + }, + intro:{ + content:'使用牌时可以额外指定$为目标', + }, + ai:{ + effect:{ + player:function(card,player,target){ + if(_status.event.getParent('useCard',true)||_status.event.getParent('_wuxie',true)) return; + if(player.getStorage('clanmingjie_effect').contains(target)) return [1,-0.5]; + }, + }, + }, + }, + targeted:{ + trigger:{ + player:'phaseEnd', + }, + filter:function(event,player){ + return player.getStorage('clanmingjie_targeted').length; + }, + forced:true, + popup:false, + onremove:['clanmingjie_targeted','clanmingjie_record'], + charlotte:true, + group:'clanmingjie_record', + content:function(){ + 'step 0' + var targets=player.getStorage('clanmingjie_targeted').slice(); + targets.sortBySeat(); + event.targets=targets; + event.targetsx=targets.slice(); + var cards=[]; + var list=player.getStorage('clanmingjie_record'); + if(list.length){ + cards.addArray(list); + } + cards=cards.filterInD('d'); + if(cards.length){ + event.cards=cards; + } + else event.goto(6); + 'step 1' + event.target=targets.shift(); + event.cards2=cards.filterInD('d'); + 'step 2' + target.chooseButton(['铭戒:是否使用这些牌?',event.cards2]).set('filterButton',button=>{ + return _status.event.player.hasUseTarget(button.link); + }).set('ai',button=>{ + return _status.event.player.getUseValue(button.link); + }); + 'step 3' + if(result.bool){ + var card=result.links[0]; + event.cards2.remove(card); + target.$gain2(card,false); + game.delayx(); + target.chooseUseTarget(card,true); + } + else event.goto(5); + 'step 4' + if(event.cards2.filter(card=>{ + return get.position(card,true)=='d'&&target.hasUseTarget(card); + }).length) event.goto(2); + 'step 5' + if(targets.length) event.goto(1); + 'step 6' + event.targetsx.forEach(target=>{ + target.unmarkAuto('clanmingjie_effect',[player]); + }); + player.removeSkill('clanmingjie_targeted'); + }, + marktext:'戒', + intro:{ + content:'已被$指定为〖铭戒〗目标', + }, + }, + record:{ + trigger:{ + global:['shaMiss','eventNeutralized','useCard1','phaseAfter'], + }, + silent:true, + forced:true, + charlotte:true, + filter:function(event,player){ + if(_status.currentPhase!=player) return false; + if(event.name=='useCard'){ + return get.suit(event.card)=='spade'; + } + if(event.name=='phase') return true; + if(event.type!='card') return false; + return true; + }, + content:function(){ + 'step 0' + if(trigger.name=='phase'){ + delete player.storage.clanmingjie_record; + return; + } + player.markAuto('clanmingjie_record',trigger.cards); + } + } + } + }, //钟琰族钟琰 clanguangu:{ audio:2, @@ -36,7 +284,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ marktext:'☯', intro:{ content:function(storage){ - return '转换技。出牌阶段限一次,你可以观看'+(storage?'一名角色的至多四张手':'牌堆顶的至多四张')+'牌,然后可以使用其中的一张牌'; + return '转换技。出牌阶段限一次,你可以观看'+(storage?'一名角色的至多四张手':'牌堆顶的至多四张')+'牌,然后可以使用其中的一张牌。'; }, }, filter:function(event,player){ @@ -132,7 +380,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ nature:get.nature(card,get.owner(card)), cards:[card], } - return player.hasUseTarget(cardx); + return player.hasUseTarget(cardx,null,false); }).set('ai',button=>{ var len=_status.event.len; var card=button.link; @@ -159,7 +407,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ nature:get.nature(card,get.owner(card)), cards:[card], } - var next=player.chooseUseTarget(cardx,[card],true).set('oncard',(card)=>{ + var next=player.chooseUseTarget(cardx,[card],true,false).set('oncard',(card)=>{ var owner=_status.event.getParent().owner; if(owner) owner.$throw(card.cards); }); @@ -337,7 +585,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, clanzhongliu:{ audio:2, - audioname:['clan_wangling'], + audioname:['clan_wangling','clan_wangyun'], trigger:{player:'useCard'}, forced:true, clanSkill:true, @@ -1870,6 +2118,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ clanxiaoyong_info:'锁定技。当你于回合内首次使用字数为X的牌时,你重置〖观骨〗(X为你上次发动〖观骨〗观看的牌数)。', clanbaozu:'保族', clanbaozu_info:'宗族技,限定技。当一名同族角色进入濒死状态时,你可以令其横置并回复1点体力。', + clan_wangyun:'族王允', + clanjiexuan:'解悬', + clanjiexuan_info:'限定技,转换技。阴:你可以将一张红色牌当【顺手牵羊】使用;阳:你可以将一张黑色牌当【过河拆桥】使用。', + clanmingjie:'铭戒', + clanmingjie_info:'限定技。出牌阶段,你可以选择一名角色,然后直到其下回合结束时,当你使用牌时你可以指定其为额外目标。然后其下回合结束时,你可以使用本回合使用过的黑桃牌和被抵消过的牌。', clan_wu:'陈留·吴氏', clan_xun:'颍川·荀氏', diff --git a/character/mobile.js b/character/mobile.js index 4f7588520..161fb7de3 100644 --- a/character/mobile.js +++ b/character/mobile.js @@ -19949,7 +19949,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ xin_zhuzhi:'手杀朱治', sbanguo:'安国', sbanguo_info:'①游戏开始时,你令一名其他角色获得1枚“安国”标记(有“安国”的角色手牌上限基数等于体力上限)。②出牌阶段开始时,你可以将一名有“安国”的角色的所有“安国”移动给一名本局游戏未获得过“安国”的其他角色。③当你受到伤害时,若有有“安国”的角色且伤害值不小于你的体力值且此伤害没有来源或来源没有“安国”,防止此伤害。④一名角色进入濒死状态时,若其有你因〖安国①〗获得的“安国”,你移去其该“安国”,令其将体力回复至1点。然后你选择一项:1.若你的体力值大于1,你失去体力至1点;2.若你的体力上限大于1,你将体力上限减至1。最后你令其获得X点护甲(X为你以此法失去的体力值或减少的体力上限)。', - wangjun:'王濬', + wangjun:'手杀王濬', zhujian:'筑舰', zhujian_info:'出牌阶段限一次。你可以令至少两名装备区里有牌的角色各摸一张牌。', duansuo:'断索', diff --git a/character/sp2.js b/character/sp2.js index 653f96842..56289d275 100644 --- a/character/sp2.js +++ b/character/sp2.js @@ -4,6 +4,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ name:'sp2', connect:true, character:{ + dc_wangjun:['male','qun',4,['dcmianyao','dcchangqu']], dc_wuban:['male','shu',4,['dcyouzhan'],['clan:陈留吴氏','unseen']], dc_duyu:['male','wei',3,['dcjianguo','dcdyqingshi'],['unseen']], ganfurenmifuren:['female','shu',3,['dcchanjuan','dcxunbie']], @@ -236,7 +237,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, characterSort:{ sp2:{ - sp_whlw:["xurong","lijue","zhangji","fanchou","guosi","duanwei","liangxing","zhangheng",'tangji','niufu'], + sp_whlw:["xurong","lijue","zhangji","fanchou","guosi","duanwei","liangxing","zhangheng",'tangji','niufu','dongxie'], sp_zlzy:["zhangqiying","lvkai","zhanggong","weiwenzhugezhi","beimihu"], sp_longzhou:["xf_tangzi","xf_huangquan","xf_sufei","sp_liuqi"], sp_zizouqi:["mangyachang","xugong","zhangchangpu"], @@ -276,10 +277,238 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sp2_yuxiu:['dongguiren','dc_tengfanglan','zhangjinyun'], sp2_gaoshan:['wanglang','liuhui'], sp2_wumiao:['wu_zhugeliang'], - sp_decade:['caobuxing','re_maliang','xin_baosanniang','dongxie'], + sp_decade:['caobuxing','re_maliang','xin_baosanniang','dc_wangjun'], } }, skill:{ + //新服灭霸 + dcmianyao:{ + audio:2, + trigger:{ + player:'phaseDrawEnd', + }, + 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){ + 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); + }, + subSkill:{ + draw:{ + trigger:{ + player:'phaseEnd', + }, + filter:function(event,player){ + return player.hasMark('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]; + }, + 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.contains(next)&&!selected.contains(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(); + }, + 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=>{ + 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).set('ai',card=>{ + if(_status.event.att>0) return 6-get.value(card); + if(_status.event.take) return -get.value(card); + return 5-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{ + return i.isIn(); + }); + if(nextPlayer){ + target.line(nextPlayer); + 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=>{ + 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); + 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 sum=0; + for(var i=0;imaxSum2){ + maxSum2=sum; + maxIndex2=i; + } + } + if(maxSummaxIndex) 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:'这里停了&艘战舰!不过啥用没有。', + } + }, + add:{ + trigger:{ + player:'damageBegin3', + }, + filter:function(event,player){ + return event.nature&&player.hasMark('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:'下次受到的属性伤害+#', + } + }, + } + }, //吴班 dcyouzhan:{ audio:2, @@ -31326,6 +31555,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcjianguo_info:'出牌阶段限一次。你可以选择一名角色并选择一项:1.令其摸一张牌,然后其弃置一半的手牌;2.令其弃置一张牌,然后其摸等同于手牌数一半的牌(均向下取整)。', dcdyqingshi:'倾势', dcdyqingshi_info:'当你于回合内使用【杀】或普通锦囊牌指定第一个目标后,若目标角色包括其他角色且此牌为你本回合使用的第X张牌,你可以对其中一名不为你的目标角色造成1点伤害(X为你的手牌数)。', + dc_wangjun:'王濬', + dcmianyao:'免徭', + dcmianyao_info:'摸牌阶段结束时,你可以展示手牌中点数最小的一张牌并将此牌随机插入牌堆中。然后你于此回合结束时摸等同于此牌点数的牌。', + dcchangqu:'长驱', + dcchangqu_info:'出牌阶段限一次。你可以开一艘战舰(你从你的上家或下家开始选择任意名座位连续的其他角色,且起点角色获得“战舰”标记)。这些角色按照你选择的顺序依次执行:{若其有本次获得的“战舰”,其选择一项:1.交给你X张手牌,然后将“战舰”移动给你选择的下一名目标角色;2.令其下次受到的属性伤害值+X,然后横置(X为本次〖长驱〗中选项一被选择过的次数且至少为1)。}。', sp_whlw:"文和乱武", sp_zlzy:"逐鹿中原", diff --git a/image/character/clan_wangyun.jpg b/image/character/clan_wangyun.jpg new file mode 100644 index 000000000..4bb5cf078 Binary files /dev/null and b/image/character/clan_wangyun.jpg differ diff --git a/image/character/dc_wangjun.jpg b/image/character/dc_wangjun.jpg new file mode 100644 index 000000000..c03b7580a Binary files /dev/null and b/image/character/dc_wangjun.jpg differ