diff --git a/card/extra.js b/card/extra.js index 12f570962..d7178ff78 100644 --- a/card/extra.js +++ b/card/extra.js @@ -281,7 +281,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ content:function(){ target.link(); }, - chongzhu:true, + recastable:true, ai:{ wuxie:function(target,card,player,viewer){ if(_status.event.getRand()<0.5) return 0; diff --git a/card/guozhan.js b/card/guozhan.js index a8fea473c..9c848a017 100644 --- a/card/guozhan.js +++ b/card/guozhan.js @@ -455,28 +455,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ return target!=player&&(get.mode()!='guozhan'||_status.mode=='yingbian'||_status.mode=='free'||target.countCards('e')>0); }, enable:true, - yingbian_prompt:function(card){ - var str=''; - if(get.cardtag(card,'yingbian_all')){ - str+='此牌的效果改为依次执行所有选项'; - } - if(!str.length||get.cardtag(card,'yingbian_add')){ - if(str.length) str+=';'; - str+='当你使用此牌选择目标后,你可为此牌增加一个目标'; - } - return str; - }, - yingbian:function(event){ - var card=event.card,bool=false; - if(get.cardtag(card,'yingbian_all')){ - bool=true; - card.yingbian_all=true; - game.log(card,'执行所有选项'); - } - if(!bool||get.cardtag(card,'yingbian_add')){ - event.yingbian_addTarget=true; - } - }, + defaultYingbianEffect:'add', content:function(){ 'step 0' if(event.card.yingbian_all){ @@ -577,7 +556,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, mode:['guozhan','versus'], filterTarget:true, - chongzhu:true, + recastable:true, changeTarget:function(player,targets){ var target=targets[0]; game.filterPlayer(function(current){ @@ -942,7 +921,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ fullskin:true, type:'trick', enable:true, - chongzhu:true, + recastable:true, filterTarget:function(card,player,target){ if(player==target) return false; return (target.countCards('h')||target.isUnseen(2)); diff --git a/card/hearth.js b/card/hearth.js index a754f5e61..9ed1320c9 100644 --- a/card/hearth.js +++ b/card/hearth.js @@ -447,7 +447,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ fullskin:true, type:'trick', enable:true, - // chongzhu:true, + // recastable:true, filterTarget:function(card,player,target){ return target==player; }, diff --git a/card/sp.js b/card/sp.js index 7aa5a6957..fc62bb820 100644 --- a/card/sp.js +++ b/card/sp.js @@ -259,7 +259,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ enable:function(){ return game.countPlayer()>2; }, - chongzhu:function(){ + recastable:function(){ return game.countPlayer()<=2; }, singleCard:true, diff --git a/card/standard.js b/card/standard.js index e18416e8e..5dd062144 100644 --- a/card/standard.js +++ b/card/standard.js @@ -100,39 +100,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ if(lib.linked.contains(card.nature)) return '出牌阶段,对你攻击范围内的一名角色使用。其须使用一张【闪】,否则你对其造成1点'+get.translation(card.nature)+'属性伤害。'; return '出牌阶段,对你攻击范围内的一名角色使用。其须使用一张【闪】,否则你对其造成1点伤害。'; }, - yingbian_prompt:function(card){ - var str=''; - if(get.cardtag(card,'yingbian_hit')){ - str+='此牌不可被响应'; - } - if(get.cardtag(card,'yingbian_damage')){ - if(str.length) str+=';'; - str+='此牌的伤害值基数+1'; - } - if(!str.length||get.cardtag(card,'yingbian_add')){ - if(str.length) str+=';'; - str+='当你使用此牌选择目标后,你可为此牌增加一个目标'; - } - return str; - }, - yingbian:function(event){ - var card=event.card,bool=false; - if(get.cardtag(card,'yingbian_hit')){ - bool=true; - event.directHit.addArray(game.players); - game.log(card,'不可被响应'); - } - if(get.cardtag(card,'yingbian_damage')){ - bool=true; - if(typeof event.baseDamage!='number') event.baseDamage=1; - event.baseDamage++; - game.log(event.card,'的伤害值基数+1'); - } - if(!bool||get.cardtag(card,'yingbian_add')){ - event.yingbian_addTarget=true; - } - }, - yingbian_tags:['hit','damage','add'], + defaultYingbianEffect:'add', filterTarget:function(card,player,target){return player!=target}, content:function(){ "step 0" @@ -387,27 +355,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ cardcolor:'red', notarget:true, nodelay:true, - yingbian_prompt:function(card){ - var str=''; - if(get.cardtag(card,'yingbian_gain')){ - str+='当你声明使用此牌时,你获得此牌响应的目标牌'; - } - if(!str.length||get.cardtag(card,'yingbian_draw')){ - if(str.length) str+=';'; - str+='当你声明使用此牌时,你摸一张牌'; - } - return str; - }, - yingbian_tags:['gain','draw'], - yingbian:function(event){ - var bool=false; - if(get.cardtag(event.card,'yingbian_gain')){ - bool=true; - var cardx=event.respondTo; - if(cardx&&cardx[1]&&cardx[1].cards&&cardx[1].cards.filterInD('od').length) event.player.gain(cardx[1].cards.filterInD('od'),'gain2','log'); - } - if(!bool||get.cardtag(event.card,'yingbian_draw')) event.player.draw(); - }, + defaultYingbianEffect:'draw', content:function(){ event.result='shaned'; event.getParent().delayx=false; @@ -889,11 +837,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ selectTarget:-1, cardcolor:'red', reverseOrder:true, - yingbian_prompt:'当你使用此牌选择目标后,你可为此牌减少一个目标', - yingbian_tags:['remove'], - yingbian:function(event){ - event.yingbian_removeTarget=true; - }, + defaultYingbianEffect:'remove', filterTarget:function(card,player,target){ //return target.hp0; }, - yingbian_tags:['all','hit','add'], - yingbian_prompt:function(card){ - var str=''; - if(get.cardtag(card,'yingbian_all')){ - str+='此牌的效果改为依次执行所有选项'; - } - if(get.cardtag(card,'yingbian_hit')){ - if(str.length) str+=';'; - str+='此牌不可被响应'; - } - if(!str.length||get.cardtag(card,'yingbian_add')){ - if(str.length) str+=';'; - str+='当你使用此牌选择目标后,你可为此牌增加一个目标'; - } - return str; - }, - yingbian:function(event){ - var card=event.card,bool=false; - if(get.cardtag(card,'yingbian_all')){ - bool=true; - card.yingbian_all=true; - game.log(card,'执行所有选项'); - } - if(get.cardtag(card,'yingbian_hit')){ - bool=true; - event.directHit.addArray(game.players); - game.log(card,'不可被响应'); - } - if(!bool||get.cardtag(card,'yingbian_add')){ - event.yingbian_addTarget=true; - } - }, + defaultYingbianEffect:'add', content:function(){ var dist=get.distance(player,target); if(dist>1||card.yingbian_all) player.discardPlayerCard(target,'hej',true); @@ -174,11 +143,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ filterTarget:function(card,player,target){ return target!=player&&target.countCards('h')>0; }, - yingbian_prompt:'当你使用此牌选择目标后,你可为此牌增加一个目标', - yingbian_tags:['add'], - yingbian:function(event){ - event.yingbian_addTarget=true; - }, + defaultYingbianEffect:'add', content:function(){ 'step 0' if(player.isDead()||!target.countCards('h')){ @@ -399,27 +364,20 @@ game.import('card',function(lib,game,ui,get,ai,_status){ global:'heiguangkai_ai', }, tongque_skill:{ - trigger:{player:'useCard1'}, + trigger:{player:'useCardBegin'}, equipSkill:true, forced:true, - filter:function(event,player){ - return !event.card.yingbian&&get.is.yingbian(event.card)&&player.getHistory('useCard',function(evt){ - return get.is.yingbian(evt.card) - }).indexOf(event)==0; - }, - content:function(){ - trigger.card.yingbian=true; - var info=get.info(trigger.card); - if(info&&info.yingbian) info.yingbian(trigger); - player.addTempSkill('yingbian_changeTarget'); - }, + filter:(event,player)=>get.is.yingbianConditional(event.card)&&!player.hasHistory('useCard',evt=>get.is.yingbianConditional(evt.card)), + content:()=>{ + trigger.forceYingbian=true; + } }, tianjitu_skill:{ audio:true, trigger:{player:['equipBegin','loseBegin']}, forced:true, equipSkill:true, - filter:(event,player,name)=>name=='equipBegin'?event.card.name=='tianjitu'&&player.hasCard(card=>card!=event.card):event.cards.some(value=>value.name=='tianjitu')&&player.countCards('h')<5, + filter:(event,player,name)=>name=='equipBegin'?event.card.name=='tianjitu'&&player.hasCard(card=>card!=event.card):event.cards.some(value=>get.position(value)=='e'&&value.name=='tianjitu')&&player.countCards('h')<5, content:()=>{ if(event.triggername=='loseBegin') player.drawTo(5); else player.chooseToDiscard(true,card=>card!=_status.event.getTrigger().card,'he'); @@ -441,10 +399,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ 'step 1' if(result.bool){ player.logSkill('taigongyinfu_skill'); - player.lose(result.cards,ui.discardPile,'visible'); - player.$throw(result.cards,1000); - game.log(player,'将',result.cards,'置入了弃牌堆'); - player.draw(); + player.recast(result.cards); } }, }, @@ -485,195 +440,63 @@ game.import('card',function(lib,game,ui,get,ai,_status){ firstDo:true, ruleSkill:true, forceLoad:true, - filter:function(event,player){ + filter:(event,player)=>{ if(event.card.yingbian) return false; - var bool=player.hasSkillTag('forceYingbian'); - var card=event.card; - if(get.cardtag(card,'yingbian_kongchao')&&(!player.countCards('h')||bool)) return true; - if(get.cardtag(card,'yingbian_canqu')&&(player.hp==1||bool)) return true; - if(get.cardtag(card,'yingbian_fujia')&&(player.isMaxHandcard()||bool)) return true; - if(get.cardtag(card,'yingbian_zhuzhan')) return true; - 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); }, - content:function(){ + content:()=>{ 'step 0' - var card=trigger.card; - event.card=card; - var bool=false; - if(get.cardtag(card,'yingbian_kongchao')&&!player.countCards('h')){ - player.popup('空巢','soil'); - bool=true; + 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; } - else if(get.cardtag(card,'yingbian_canqu')&&player.hp==1){ - player.popup('残躯','fire'); - bool=true; - } - else if(get.cardtag(card,'yingbian_fujia')&&player.isMaxHandcard()){ - player.popup('富甲','orange'); - bool=true; - } - else if(player.hasSkillTag('forceYingbian')){ - player.popup('应变','metal'); - bool=true; - } - if(bool){ - game.log(player,'触发了',card,'的应变条件'); - event.goto(10); + if(yingbianConditionSatisfied){ + game.log(player,'触发了',event.card,'的应变条件'); + event.goto(4); } + else if((event.num=0)>=(event.yingbianConditions=get.complexYingbianConditions()).length) event.finish(); 'step 1' - event._global_waiting=true; - event.send=function(player,card,source,targets,id,id2,skillState){ - if(skillState){ - player.applySkills(skillState); - } - var type=get.type2(card); - var str=get.translation(source); - if(targets&&targets.length){ - str+='对'; - str+=get.translation(targets); - } - str+='使用了'; - var next=player.chooseCard({ - filterCard:function(card){ - return get.type2(card)==type&&lib.filter.cardDiscardable.apply(this,arguments); - }, - prompt:str+=(get.translation(card)+',是否弃置一张'+get.translation(type)+'为其助战?'), - position:'h', - _global_waiting:true, - id:id, - id2:id2, - ai:function(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){ - _status.event._resultid=id; - game.resume(); - } - }; + 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' - var type=get.type2(card); - var list=game.filterPlayer(function(current){ - if(current==player) return false; - if(!current.countCards('h')) return false; - return _status.connectMode||current.countCards('h',function(cardx){ - return get.type2(cardx)==type; - }) - }); - 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'); - }); + if(result.bool) event.goto(4); 'step 3' - if(event.list.length==0){ - event.finish(); - return; - } - else if(_status.connectMode&&(event.list[0].isOnline()||event.list[0]==game.me)){ - event.goto(5); - } - else{ - event.current=event.list.shift(); - event.send(event.current,event.card,player,trigger.targets,event.id,trigger.parent.id); - } - 'step 4' - if(result.bool){ - event.zhuzhanresult=event.current; - event.zhuzhanresult2=result; - if(event.current!=game.me) game.delayx(); - event.goto(9); - } - else{ - event.goto(3); - } - 'step 5' - var id=event.id; - var sendback=function(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 (function(){ - 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 (function(){ - event.resultOL=_status.event.resultOL; - }); - } - } - }; - - var withme=false; - var withol=false; - var list=event.list; - for(var i=0;i{ + 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)){ + lib.yingbian.effect.get(defaultYingbianEffect)(trigger); + if(!yingbianEffectExecuted) yingbianEffectExecuted=true; + } + } + if(yingbianEffectExecuted) player.addTempSkill('yingbian_changeTarget'); } }, yingbian_changeTarget:{ @@ -814,15 +637,16 @@ game.import('card',function(lib,game,ui,get,ai,_status){ yingbian_kongchao_tag:'空巢', yingbian_fujia_tag:'富甲', yingbian_canqu_tag:'残躯', + yingbian_force_tag:'应变', _yingbian:'应变', yingbian_changeTarget:'应变', yingbian_add_tag:'(目标+)', yingbian_remove_tag:'(目标-)', - yingbian_draw_tag:'(摸牌)', - yingbian_all_tag:'(双项)', - yingbian_hit_tag:'(强命)', - yingbian_gain_tag:'(反甲)', yingbian_damage_tag:'(伤害+)', + yingbian_draw_tag:'(摸牌)', + yingbian_gain_tag:'(反甲)', + yingbian_hit_tag:'(强命)', + yingbian_all_tag:'(双项)' }, list:[ ['spade',1,'juedou'], diff --git a/card/yongjian.js b/card/yongjian.js index e054d12ac..31702afed 100644 --- a/card/yongjian.js +++ b/card/yongjian.js @@ -613,10 +613,10 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, ai:{expose:0.1}, }, - _yongjian_zengyu:{ + _gifting:{ enable:'phaseUse', forceLoad:true, - filter:(event,player)=>player.hasCard(card=>lib.skill._yongjian_zengyu.filterCard(card,player),lib.skill._yongjian_zengyu.position), + 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', @@ -677,8 +677,8 @@ game.import('card',function(lib,game,ui,get,ai,_status){ xinge_info:'出牌阶段限一次。你可以将一张手牌交给一名其他角色。', xinge_append:'咕咕咕。', - _yongjian_zengyu:'赠予', - _yongjian_zengyu_info:'出牌阶段,你可将一张拥有“赠”标签的手牌区装备牌置于一名其他角色的装备区内,或将一张拥有“赠”标签的手牌区非装备牌正面朝上交给一名其他角色。', + _gifting:'赠予', + _gifting_info:'出牌阶段,你可将一张拥有“赠”标签的手牌区装备牌置于一名其他角色的装备区内,或将一张拥有“赠”标签的手牌区非装备牌正面朝上交给一名其他角色。', }, list:[ ['spade',1,'guaguliaodu'], diff --git a/card/yunchou.js b/card/yunchou.js index cf71b6945..ca76a5e3c 100644 --- a/card/yunchou.js +++ b/card/yunchou.js @@ -276,7 +276,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ enable:function(){ return game.countPlayer()>2; }, - chongzhu:function(){ + recastable:function(){ return game.countPlayer()<=2; }, multicheck:function(card,player){ diff --git a/card/zhenfa.js b/card/zhenfa.js index 501d878ac..3a363ddc2 100644 --- a/card/zhenfa.js +++ b/card/zhenfa.js @@ -5,7 +5,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ card:{ pozhenjue:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:true, notarget:true, content:function(){ @@ -25,7 +25,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, changshezhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(card,player){ if(player.inline()) return true; if(player.identity=='unknown'||player.identity=='ye') return false; @@ -68,7 +68,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, tianfuzhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(){ return game.hasPlayer(function(current){ return current.isMajor(); @@ -94,7 +94,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, dizaizhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(){ return game.hasPlayer(function(current){ return current.isNotMajor(); @@ -121,7 +121,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, fengyangzhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:true, filterTarget:function(card,player,target){ return target.sieged(); @@ -142,7 +142,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, yunchuizhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:true, filterTarget:function(card,player,target){ return target.siege(); @@ -163,7 +163,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, qixingzhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(card,player){ return player.siege()||player.sieged(); }, @@ -202,7 +202,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, shepanzhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(card,player){ if(player.identity=='unknown'||player.identity=='ye') return false; if(get.population(player.identity)<=1) return false; @@ -231,7 +231,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, longfeizhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(card,player){ return player.next.siege(player); }, @@ -261,7 +261,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, huyizhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(card,player){ return player.siege(player.next)||player.siege(player.previous); }, @@ -309,7 +309,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, niaoxiangzhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:true, filterTarget:function(card,player,target){ if(player.identity==target.identity) return false; diff --git a/character/diy.js b/character/diy.js index 6048a0b46..576b4ae5b 100755 --- a/character/diy.js +++ b/character/diy.js @@ -4262,25 +4262,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, asara_yingwei:{ - trigger:{player:'useCard1'}, + trigger:{player:'useCardBegin'}, forced:true, - 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].contains('asara_yingwei')) return true; - } - return false; - }).length>0; - }, - content:function(){ - if(!trigger.card.yingbian){ - trigger.card.yingbian=true; - var info=get.info(trigger.card); - if(info&&info.yingbian) info.yingbian(trigger); - player.addTempSkill('yingbian_changeTarget'); - } - }, + filter:event=>event.card.isCard&&event.cards.some(value=>value.hasGaintag('asara_yingwei')), + content:()=>{ + trigger.forceYingbian=true; + } }, yukito_kongwu:{ enable:'phaseUse', diff --git a/character/extra.js b/character/extra.js index d6246f22b..4e36da0ea 100755 --- a/character/extra.js +++ b/character/extra.js @@ -1010,9 +1010,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ else if(lib.translate[name+'_info']){ str+=(''+lib.translate[name+'_info']+'|'); } - if(lib.card[name].yingbian_prompt&&get.is.yingbian(node)){ - if(typeof lib.card[name].yingbian_prompt=='function') str+=('应变:'+lib.card[name].yingbian_prompt(node)+'|'); - else str+=('应变:'+lib.card[name].yingbian_prompt+'|'); + 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(';')}|`; } return str; }, @@ -2337,199 +2341,30 @@ game.import('character',function(lib,game,ui,get,ai,_status){ group:'hina_shenshi_yingbian', }, hina_shenshi_yingbian:{ - trigger:{player:'useCard1'}, + trigger:{player:'useCardBegin'}, forced:true, - filter:function(event,player){ - return event.cards.length==1&&!event.card.yingbian&&player.hasHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].contains('hina_shenshi')) return true; - } - return false; - })&&Array.isArray(get.info(event.card).yingbian_tags); - }, - content:function(){ - if(!trigger.card.yingbian){ - trigger.card.yingbian=true; - var info=get.info(trigger.card); - trigger.card.cardtags=info.yingbian_tags.map(function(i){ - return 'yingbian_'+i; - }); - if(info&&info.yingbian) info.yingbian(trigger); - player.addTempSkill('yingbian_changeTarget'); - } - }, + filter:event=>event.card.isCard&&event.cards.some(value=>value.hasGaintag('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:'useCard1'}, usable:1, - filter:function(event,player){ - return player.group=='key'&&!event.card.yingbian&&Array.isArray(get.info(event.card).yingbian_tags); - }, - content:function(){ + filter:(event,player)=>player.group=='key'&&!event.card.yingbian&&lib.yingbian.condition.complex.has('zhuzhan'), + content:()=>{ 'step 0' - var info=get.info(trigger.card); - trigger.card.cardtags=info.yingbian_tags.map(function(i){ - return 'yingbian_'+i; - }); - event.card=trigger.card; - event._global_waiting=true; - event.send=function(player,card,source,targets,id,id2,skillState){ - if(skillState){ - player.applySkills(skillState); - } - var type=get.type2(card); - var str=get.translation(source); - if(targets&&targets.length){ - str+='对'; - str+=get.translation(targets); - } - str+='使用了'; - var next=player.chooseCard({ - filterCard:function(card){ - return get.type2(card)==type&&lib.filter.cardDiscardable.apply(this,arguments); - }, - prompt:str+=(get.translation(card)+',是否弃置一张'+get.translation(type)+'为其助战?'), - position:'h', - _global_waiting:true, - id:id, - id2:id2, - ai:function(cardx){ - 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; - } - if(get.attitude(player,source)<=0) return 0; - return Math.max(ai,6)-get.value(cardx); - }, - }); - if(game.online){ - _status.event._resultid=id; - game.resume(); - } - }; + trigger.afterYingbianZhuzhan=event=>event.zhuzhanresult.draw(2); + lib.yingbian.condition.complex.get('zhuzhan')(trigger); 'step 1' - var type=get.type2(card); - var list=game.filterPlayer(function(current){ - if(current==player) return false; - if(!current.countCards('h')) return false; - return _status.connectMode||current.countCards('h',function(cardx){ - return get.type2(cardx)==type; - }) - }); - 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){ - event.finish(); - return; - } - 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,player,trigger.targets,event.id,trigger.parent.id); - } - '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; - var sendback=function(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 (function(){ - 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 (function(){ - event.resultOL=_status.event.resultOL; - }); - } - } - }; - - var withme=false; - var withol=false; - var list=event.list; - for(var i=0;igame.yingbianEffect(trigger,value)); + player.addTempSkill('yingbian_changeTarget'); + } }, yingba:{ audio:2, diff --git a/character/offline.js b/character/offline.js index ae53a698b..14311104a 100644 --- a/character/offline.js +++ b/character/offline.js @@ -3647,7 +3647,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ result:{player:1}, effect:{ target:function(card,player,target){ - if(card&&get.type(card)=='equip'&&_status.event.skill=='_yongjian_zengyu') return 0; + if(card&&get.type(card)=='equip'&&_status.event.skill=='_gifting') return 0; }, }, }, diff --git a/character/shiji.js b/character/shiji.js index fdba6b25c..7bdca8b68 100644 --- a/character/shiji.js +++ b/character/shiji.js @@ -6147,7 +6147,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } return true; }, - chongzhu:true, + recastable:true, selectTarget:2, postAi:()=>true, contentBefore:function(){ diff --git a/game/game.js b/game/game.js index 3cd762400..4b168d96a 100644 --- a/game/game.js +++ b/game/game.js @@ -29,7 +29,7 @@ } } } - var _status={ + const _status={ paused:false, paused2:false, paused3:false, @@ -59,12 +59,13 @@ yingbian_kongchao:[], yingbian_fujia:[], yingbian_canqu:[], + yingbian_force:[] }, renku:[], prehidden_skills:[], postReconnect:{}, }; - var lib={ + const lib={ configprefix:'noname_0.9_', versionOL:27, updateURLS:{ @@ -149,6 +150,176 @@ }, } }, + yingbian:{ + condition:{ + color:new Map([ + ['zhuzhan','wood'], + ['kongchao','soil'], + ['fujia','orange'], + ['canqu','fire'], + ['force','metal'] + ]), + complex:new Map([ + ['zhuzhan',function(event){ + const yingbianZhuzhan=game.createEvent('yingbianZhuzhan'); + yingbianZhuzhan.player=event.player; + yingbianZhuzhan.card=event.card; + yingbianZhuzhan._trigger=event; + yingbianZhuzhan.afterYingbianZhuzhan=event.afterYingbianZhuzhan; + yingbianZhuzhan.setContent(()=>{ + 'step 0' + event._global_waiting=true; + event.send=(player,card,source,targets,id,id2,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:cardx=>{ + var info=get.info(card); + if(info&&info.ai&&info.ai.yingbian){ + var ai=info.ai.yingbian(card,source,targets,player); + if(!ai) return 0; + return ai-get.value(cardx); + } + else if(get.attitude(player,source)<=0) return 0; + return 5-get.value(cardx); + } + }); + if(!game.online) return; + _status.event._resultid=id; + game.resume(); + }; + 'step 1' + var type=get.type2(card); + event.list=game.filterPlayer(current=>current!=player&¤t.countCards('h')&&(_status.connectMode||current.hasCard(cardx=>get.type2(cardx)==type,'h'))).sortBySeat(_status.currentPhase||player); + event.id=get.id(); + 'step 2' + if(!event.list.length) event.finish(); + else if(_status.connectMode&&(event.list[0].isOnline()||event.list[0]==game.me)) event.goto(4); + else event.send(event.current=event.list.shift(),event.card,player,trigger.targets,event.id,trigger.parent.id); + '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{ + if(value!=player) value.showTimer(); + }); + event.withol=withol; + 'step 5' + if(!result||!result.bool||event.zhuzhanresult) return; + game.broadcast('cancel',event.id); + event.zhuzhanresult=game.me; + event.zhuzhanresult2=result; + 'step 6' + if(event.withol&&!event.resultOL) game.pause(); + 'step 7' + game.players.forEach(value=>value.hideTimer()); + 'step 8' + if(event.zhuzhanresult){ + var target=event.zhuzhanresult; + target.line(player,'green'); + target.discard(event.zhuzhanresult2.cards).discarder=target; + if(typeof event.afterYingbianZhuzhan=='function') event.afterYingbianZhuzhan(event,trigger); + var yingbianCondition=event.name.slice(8).toLowerCase(),yingbianConditionTag=`yingbian_${yingbianCondition}_tag`; + target.popup(yingbianConditionTag,lib.yingbian.condition.color.get(yingbianCondition)); + game.log(target,'响应了',player,'发起的',yingbianConditionTag); + target.addExpose(0.2); + event.result={ + bool:true + } + } + else event.result={ + bool:false + }; + }); + yingbianZhuzhan._args=Array.from(arguments); + return yingbianZhuzhan; + }] + ]), + simple:new Map([ + ['kongchao',event=>!event.player.countCards('h')], + ['fujia',event=>event.player.isMaxHandcard()], + ['canqu',event=>event.player.getHp()==1] + ]) + }, + effect:new Map([ + ['add',()=>{ + trigger.yingbian_addTarget=true; + }], + ['remove',()=>{ + trigger.yingbian_removeTarget=true; + }], + ['damage',()=>{ + if(typeof trigger.baseDamage!='number') trigger.baseDamage=1; + trigger.baseDamage++; + game.log(card,'的伤害值基数+1'); + }], + ['draw',()=>{ + player.draw(); + }], + ['gain',()=>{ + const cardx=trigger.respondTo; + if(cardx&&cardx[1]&&cardx[1].cards&&cardx[1].cards.filterInD('od').length) player.gain(cardx[1].cards.filterInD('od'),'gain2'); + }], + ['hit',()=>{ + trigger.directHit.addArray(game.players).addArray(game.dead); + game.log(card,'不可被响应'); + }], + ['all',()=>{ + card.yingbian_all=true; + game.log(card,'执行所有选项'); + }] + ]), + prompt:new Map([ + ['add','当你使用此牌选择目标后,你可为此牌增加一个目标'], + ['remove','当你使用此牌选择目标后,你可为此牌减少一个目标'], + ['damage','此牌的伤害值基数+1'], + ['draw','当你声明使用此牌时,你摸一张牌'], + ['gain','当你声明使用此牌时,你获得此牌响应的目标牌'], + ['hit','此牌不可被响应'], + ['all','此牌的效果改为依次执行所有选项'] + ]) + }, characterDialogGroup:{ '收藏':function(name,capt){ return lib.config.favouriteCharacter.contains(name)?capt:null; @@ -10618,7 +10789,7 @@ eight:'八', nine:'九', ten:'十', - _chongzhu:'重铸', + _recasting:'重铸', _lianhuan:'连环', _lianhuan2:'连环', _kamisha:'神杀', @@ -28484,8 +28655,8 @@ if(!mod) return false; if(strict&&mod=='unchanged'){ if(get.position(card)!='h') return false; - const info=get.info(card); - return typeof info.chongzhu=='function'?info.chongzhu(_status.event,player):info.chongzhu; + const info=get.info(card),recastable=info.recastable||info.chongzhu; + return Boolean(typeof recastable=='function'?recastable(_status.event,player):recastable); } return true; }, @@ -30109,18 +30280,17 @@ } } }, - _chongzhu:{ + _recasting:{ enable:'phaseUse', logv:false, - visible:true, prompt:'将要重铸的牌置入弃牌堆并摸一张牌', - filter:(event,player)=>player.hasCard(card=>lib.skill._chongzhu.filterCard(card,player),'he'), + filter:(event,player)=>player.hasCard(card=>lib.skill._recasting.filterCard(card,player),lib.skill._recasting.position), position:'he', filterCard:(card,player)=>player.canRecast(card,null,true), discard:false, lose:false, delay:false, - content:function(){ + content:()=>{ player.recast(cards,null,(player,cards)=>{ var numberOfCardsToDraw=cards.length; cards.forEach(value=>{ @@ -30204,6 +30374,71 @@ player.link(); if(trigger.getParent().notLink()) trigger.getParent().lianhuanable=true; } + }, + //Deprecated skills + _chongzhu:{ + get filter(){ + return lib.skill._recasting.filter; + }, + set filter(filter){ + lib.skill._recasting.filter=filter; + }, + get filterCard(){ + return lib.skill._recasting.filterCard; + }, + set filterCard(filterCard){ + lib.skill._recasting.filterCard=filterCard; + }, + get content(){ + return lib.skill._recasting.content; + }, + set content(content){ + lib.skill._recasting.content=content; + }, + get ai(){ + return lib.skill._recasting.ai; + }, + set ai(ai){ + lib.skill._recasting.ai=ai; + } + }, + _yongjian_zengyu:{ + get filter(){ + return lib.skill._gifting.filter; + }, + set filter(filter){ + lib.skill._gifting.filter=filter; + }, + get filterCard(){ + return lib.skill._gifting.filterCard; + }, + set filterCard(filterCard){ + lib.skill._gifting.filterCard=filterCard; + }, + get filterTarget(){ + return lib.skill._gifting.filterTarget; + }, + set filterTarget(filterTarget){ + lib.skill._gifting.filterTarget=filterTarget; + }, + get check(){ + return lib.skill._gifting.check; + }, + set check(check){ + lib.skill._gifting.check=check; + }, + get content(){ + return lib.skill._gifting.content; + }, + set content(content){ + lib.skill._gifting.content=content; + }, + get ai(){ + return lib.skill._gifting.ai; + }, + set ai(ai){ + lib.skill._gifting.ai=ai; + } } }, character:{}, @@ -31325,7 +31560,23 @@ '妹子,交个朋友吧', ], }; - var game={ + const game={ + //Yingbian + //应变 + yingbianEffect:function(event,content){ + const yingbianEffect=game.createEvent('yingbianEffect'); + yingbianEffect.player=event.player; + yingbianEffect.card=event.card; + yingbianEffect._trigger=event; + yingbianEffect.setContent(content); + yingbianEffect._args=Array.from(arguments); + return yingbianEffect; + }, + setYingbianConditionColor:(yingbianCondition,color)=>game.broadcastAll((yingbianCondition,color)=>lib.yingbian.condition.color.set(yingbianCondition,color),yingbianCondition,color), + setComplexYingbianCondition:(yingbianCondition,condition)=>game.broadcastAll((yingbianCondition,condition)=>lib.yingbian.condition.complex.set(yingbianCondition,condition),yingbianCondition,condition), + setSimpleYingbianCondition:(yingbianCondition,condition)=>game.broadcastAll((yingbianCondition,condition)=>lib.yingbian.condition.simple.set(yingbianCondition,condition),yingbianCondition,condition), + setYingbianEffect:(yingbianEffect,effect)=>game.broadcastAll((yingbianEffect,effect)=>lib.yingbian.effect.set(yingbianEffect,effect),yingbianEffect,effect), + setYingbianPrompt:(yingbian,prompt)=>game.broadcastAll((yingbian,prompt)=>lib.yingbian.prompt.set(yingbian,prompt),yingbian,prompt), //Add a background music to the config option //在设置选项中添加一首背景音乐 addBackgroundMusic:(link,musicName,aozhan)=>{ @@ -38570,7 +38821,7 @@ shuffleNumber:0, }; window['b'+'ann'+'e'+'dE'+'x'+'ten'+'s'+'i'+'o'+'ns']=['\u4fa0\u4e49','\u5168\u6559\u7a0b']; - var ui={ + const ui={ updates:[], thrown:[], touchlines:[], @@ -52673,7 +52924,32 @@ ui._recycle[key]=node; }, }; - var get={ + const get={ + //Yingbian + //应变 + //Get the Yingbian conditions (of the card) + //获取(此牌的)应变条件 + yingbianConditions:card=>get.complexYingbianConditions(card).concat(get.simpleYingbianConditions(card)), + complexYingbianConditions:card=>{ + const complexYingbianConditions=Array.from(lib.yingbian.condition.complex.keys()); + return card?complexYingbianConditions.filter(value=>get.cardtag(card,`yingbian_${value}`)):complexYingbianConditions; + }, + simpleYingbianConditions:card=>{ + const simpleYingbianConditions=Array.from(lib.yingbian.condition.simple.keys()) + return card?simpleYingbianConditions.filter(value=>get.cardtag(card,`yingbian_${value}`)):simpleYingbianConditions; + }, + //Get the Yingbian effects (of the card) + //获取(此牌的)应变效果 + yingbianEffects:card=>{ + const yingbianEffects=Array.from(lib.yingbian.effect.keys()); + return card?yingbianEffects.filter(value=>get.cardtag(card,`yingbian_${value}`)):yingbianEffects; + }, + //Get the default Yingbian effect of the card + //获取此牌的默认应变效果 + defaultYingbianEffect:card=>{ + const info=get.info(card); + return info&&info.defaultYingbianEffect||null; + }, //优先度判断 priority:function(skill){ const info=get.info(skill); @@ -52871,9 +53147,30 @@ } return false; }, - yingbian:function(node){ - return get.cardtag(node,'yingbian_zhuzhan')||get.cardtag(node,'yingbian_fujia')||get.cardtag(node,'yingbian_canqu')||get.cardtag(node,'yingbian_kongchao'); + //Check if the card has a Yingbian condition + //检测此牌是否具有应变条件 + yingbianConditional:card=>get.is.complexlyYingbianConditional(card)||get.is.simplyYingbianConditional(card), + complexlyYingbianConditional:card=>{ + for(const key of lib.yingbian.condition.complex.keys()){ + if(get.cardtag(card,`yingbian_${key}`)) return true; + } + return false; }, + simplyYingbianConditional:card=>{ + for(const key of lib.yingbian.condition.simple.keys()){ + if(get.cardtag(card,`yingbian_${key}`)) return true; + } + return false; + }, + //Check if the card has a Yingbian effect + //检测此牌是否具有应变效果 + yingbianEffective:card=>{ + for(const key of lib.yingbian.effect.keys()){ + if(get.cardtag(card,`yingbian_${key}`)) return true; + } + return false; + }, + yingbian:card=>get.is.yingbianConditional(card)||get.is.yingbianEffective(card), emoji:function(substring){ if(substring){ var reg=new RegExp("[~#^$@%&!?%*]",'g'); @@ -56148,9 +56445,13 @@ uiintro._place_text=placetext; } } - if(lib.card[name].yingbian_prompt&&get.is.yingbian(node.link||node)){ - if(typeof lib.card[name].yingbian_prompt=='function') uiintro.add('
应变:'+lib.card[name].yingbian_prompt(node.link||node)+'
'); - else uiintro.add('
应变:'+lib.card[name].yingbian_prompt+'
'); + if(get.is.yingbianConditional(node.link||node)){ + const yingbianEffects=get.yingbianEffects(node.link||node); + if(!yingbianEffects.length){ + const defaultYingbianEffect=get.defaultYingbianEffect(node.link||node); + if(lib.yingbian.prompt.has(defaultYingbianEffect)) yingbianEffects.push(defaultYingbianEffect); + } + if(yingbianEffects.length) uiintro.add(`
应变:${yingbianEffects.map(value=>lib.yingbian.prompt.get(value)).join(';')}
`); } if(lib.translate[name+'_append']){ uiintro.add('
'+lib.translate[name+'_append']+'
'); @@ -57234,7 +57535,7 @@ return get.attitude(_status.event.player,to); }, }; - var ai={ + const ai={ basic:{ chooseButton:function(check){ var event=_status.event; diff --git a/layout/default/layout.css b/layout/default/layout.css index 999b9abe5..fdbc3e9fb 100644 --- a/layout/default/layout.css +++ b/layout/default/layout.css @@ -4536,11 +4536,13 @@ div[data-decoration="bronze"]::after{ right: 6px; } .card .tempname { - top: 6px; - left: 6px; - font-size: 22px; color: white !important; + font-size: 22px; + left: 8px; pointer-events: none; + top: 4px; + writing-mode: vertical-rl; + -webkit-writing-mode: vertical-rl; } /*.card.equip1 .wunature, .card.equip3 .wunature, diff --git a/mode/boss.js b/mode/boss.js index 9f7dd71b9..e8773a99d 100644 --- a/mode/boss.js +++ b/mode/boss.js @@ -8359,7 +8359,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ } }); for(var i in lib.card){ - if(lib.card[i].subtype=='equip1') lib.card[i].chongzhu=true; + if(lib.card[i].subtype=='equip1') lib.card[i].recastable=true; } } }, diff --git a/mode/brawl.js b/mode/brawl.js index 0676f7851..7b6ee0095 100644 --- a/mode/brawl.js +++ b/mode/brawl.js @@ -480,7 +480,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ hhzz_toulianghuanzhu:{ enable:true, cardimage:"toulianghuanzhu", - chongzhu:true, + recastable:true, type:'trick', filterTarget:function(card,player,target){ return target.skillH.length>0; diff --git a/mode/stone.js b/mode/stone.js index 59b79537b..c03fd8282 100644 --- a/mode/stone.js +++ b/mode/stone.js @@ -583,7 +583,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ enable:function(event,player){ return player.canAddFellow(); }, - chongzhu:function(event,player){ + recastable:function(event,player){ return !player.isMin()&&!player.canAddFellow(); }, notarget:true, @@ -1424,7 +1424,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ lib.card.list.randomSort(); } - lib.skill._chongzhu.usable=3; + lib.skill._recasting.usable=3; for(i in lib.skill){ if(lib.skill[i].changeSeat){ lib.skill[i]={}; @@ -2366,7 +2366,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ type:'stonecard', stoneact:2, career:'priest', - chongzhu:true, + recastable:true, enable:function(event,player){ if(player.career!='priest') return false; return !player.storage.anyingxingtai||player.storage.anyingxingtai<2;