diff --git a/character/clan.js b/character/clan.js index 7389bacf4..70577a94e 100644 --- a/character/clan.js +++ b/character/clan.js @@ -1172,6 +1172,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ delete player.storage[skill+'_roundcount']; resetSkills.add(skill); } + if(player.storage[`temp_ban_${skill}`]){ + delete player.storage[`temp_ban_${skill}`]; + } if(player.awakenedSkills.contains(skill)){ player.restoreSkill(skill); resetSkills.add(skill); diff --git a/character/huicui.js b/character/huicui.js index 8b8e42c0f..de0cc6ca4 100644 --- a/character/huicui.js +++ b/character/huicui.js @@ -4,6 +4,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ name:'huicui', connect:true, character:{ + 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']], @@ -91,7 +93,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ characterSort:{ huicui:{ sp_baigei:['re_panfeng','xingdaorong','caoxing','re_chunyuqiong','xiahoujie','dc_caiyang','zhoushan'], - sp_caizijiaren:['re_dongbai','re_sunluyu','heyan','zhaoyan','wangtao','wangyue','zhangxuan','tengyin','zhangyao','xiahoulingnv','dc_sunru'], + sp_caizijiaren:['re_dongbai','re_sunluyu','heyan','zhaoyan','wangtao','wangyue','zhangxuan','tengyin','zhangyao','xiahoulingnv','dc_sunru','pangshanmin'], sp_zhilan:['liuyong','wanniangongzhu','zhanghu','lvlingqi','tenggongzhu','panghui','dc_zhaotongzhaoguang','yuantanyuanxiyuanshang','yuechen'], sp_guixin:['re_kanze','re_chendeng','caimaozhangyun','dc_lvkuanglvxiang','dc_gaolan','yinfuren','chengui','chenjiao','dc_sp_jiaxu','qinlang'], sp_daihan:['mamidi','dc_jiling','zhangxun','dc_yuejiu','wanglie','leibo','qiaorui','dongwan','yuanyin'], @@ -102,10 +104,168 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sp_jishi:['dc_jiben','zhenghun','dc_sunhanhua','liuchongluojun'], sp_raoting:['dc_huanghao','dc_sunziliufang','dc_sunchen','dc_jiachong'], sp_yijun:['gongsundu','mengyou'], - sp_zhengyin:['yue_caiwenji','yue_zhoufei'], + sp_zhengyin:['yue_caiwenji','yue_zhoufei','yue_caiyong'], } }, skill:{ + //乐蔡邕 + dcjiaowei:{ + audio:2, + trigger:{ + global:'phaseBefore', + player:'enterGame' + }, + 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'); + }, + 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; + }, + }, + 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')); + }, + 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'; + }); + if(player.countCards('h')-cards.length<=num) return 'zeroplayertarget'; + } + }, + }, + }, + }, + }, + }, + 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); + 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; + }); + }, + 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='五字不行哇'; + player.chat(str); + game.log(`但是找不到字数为${len}的牌!`); + } + if(player.countCards('h',card=>card.hasGaintag('dcjiaowei_tag'))<=len){ + player.storage.counttrigger.dcfeibai--; + 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; + }); + if(cardx) return num+8+(len==2||len==4?2:0); + }, + } + }, + //庞山民 + dccaisi:{ + audio:2, + trigger:{player:'useCardAfter'}, + filter:function(event,player){ + if(get.type(event.card)!='basic') return false; + if(player.getHistory('gain',evt=>evt.getParent().name=='dccaisi').length>player.maxHp) return false; + return _status.currentPhase; + }, + prompt2:function(event,player){ + return `从${player==_status.currentPhase?'牌堆':'弃牌'}堆中随机获得一张非基本牌`; + }, + content:function*(event,map){ + const player=map.player,trigger=map.trigger; + const position=player==_status.currentPhase?'cardPile':'discardPile'; + const card=get[position](card=>{ + return get.type(card,false)!='basic'; + }); + if(card){ + player.gain(card,'gain2'); + } + else{ + player.chat('没有非基本牌…'); + game.log(`但是${position=='discardPile'?'弃':''}牌堆里没有非基本牌!`); + + } + }, + }, + dczhuoli:{ + audio:2, + trigger:{global:'phaseEnd'}, + forced:true, + filter:function(event,player){ + return player.getHistory('useCard').length>player.maxHp; + }, + content:function*(event,map){ + const player=map.player; + if(player.maxHp{_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; + }) + 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; + } + } + 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'); + } + 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])) 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){ + 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; + }, + 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).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, @@ -13039,6 +13162,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcxiaoyin_info:'①准备阶段,你可以亮出牌堆顶的Y张牌(Y为你距离1以内的角色数),获得其中的红色牌,将其中任意张黑色牌置于等量名座次连续的其他角色的武将牌上,称为“硝引”。②当一名有“硝引”牌的角色受到伤害时,若此伤害为:火焰伤害,来源可以弃置一张其“硝引”牌包含的类型的牌,将其“硝引”置入弃牌堆,令此伤害+1;非火焰伤害,来源可以获得其“硝引”牌,将此伤害改为火焰伤害。', dchuahuo:'花火', dchuahuo_info:'出牌阶段限一次。你可以将一张红色手牌当不计入次数的火【杀】使用。然后当你使用此牌指定第一个目标后,若目标角色有“硝引”牌,你可以将此【杀】的目标改为所有有“硝引”牌的角色。', + caoyi:'曹轶', + dcmiyi:'蜜饴', + dcmiyi_info:'准备阶段,你可以选择一项:1.回复1点体力;2.受到你造成的1点伤害。然后你令任意名角色执行该项。若如此做,这些角色于结束阶段执行另一项。', + dcyinjun:'寅君', + dcyinjun_info:'当你使用对应实体牌均为你的手牌的【杀】或锦囊牌结算结束后,若此牌目标为1,你可以视为对该目标使用一张无伤害来源的【杀】。然后若你本回合发动〖寅君〗的次数大于你的体力值,〖寅君〗失效直到回合结束。', sp2_yinyu:'隐山之玉', sp2_huben:'百战虎贲', diff --git a/game/game.js b/game/game.js index 2e298f74a..86ee7e6b7 100644 --- a/game/game.js +++ b/game/game.js @@ -27741,6 +27741,23 @@ return skill; } + tempBanSkill(skill,expire,log){ + if(!this.hasSkill(skill)||this.hasStorage(`temp_ban_${skill}`)) return; + this.setStorage(`temp_ban_${skill}`,true); + + if(log!==false) 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).assign({ + firstDo:true, + }).vars({ + bannedSkill:skill, + }).then(()=>{ + delete player.storage[`temp_ban_${bannedSkill}`]; + }) + return skill; + } attitudeTo(target){ if(typeof get.attitude=='function') return get.attitude(this,target); return 0; @@ -32674,6 +32691,7 @@ if(info.round&&(info.round-(game.roundNumber-player.storage[skill+'_roundcount'])>0)){ return false; } + if(player.storage[`temp_ban_${skill}`]===true) return false; return true; }, characterDisabled:function(i,libCharacter){ @@ -41576,6 +41594,7 @@ if(info.usable&&get.skillCount(skills2[i])>=info.usable) enable=false; if(info.chooseButton&&_status.event.noButton) enable=false; if(info.round&&(info.round-(game.roundNumber-player.storage[skills2[i]+'_roundcount'])>0)) enable=false; + if(player.storage[`temp_ban_${skills2[i]}`]===true) enable=false; } if(enable){ if(event.isMine()||!event._aiexclude.contains(skills2[i])){