From 85c9db60acaf752816b250fb0e244d78e5b77944 Mon Sep 17 00:00:00 2001 From: copcap Date: Sun, 5 Nov 2023 23:49:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=B7=E5=A4=96=E6=9C=8D=E6=96=B0=E5=B0=86?= =?UTF-8?q?=E8=B0=83=E6=95=B4&bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- character/tw.js | 169 +++++++++++++++++++++++++----------------------- game/game.js | 24 ++++++- 2 files changed, 109 insertions(+), 84 deletions(-) diff --git a/character/tw.js b/character/tw.js index 2b540c0f6..082bcf629 100644 --- a/character/tw.js +++ b/character/tw.js @@ -127,8 +127,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ kaisa:["male","western",4,["zhengfu"]], }, characterIntro:{ - xiahousone:'三国杀集换式卡牌游戏《阵面对决》中的裂土系列卡牌。游卡桌游官方原创的三国时期女性角色。', - zhangwei:'三国杀集换式卡牌游戏《阵面对决》中的帝畿系列卡牌。游卡桌游官方原创的三国时期女性角色。', + xiahousone:'夏侯子萼,游卡桌游《三国杀阵面对决》中虚构的人物。在《阵面对决》中,设定为在貂蝉不在时血婆娑的实际首领。在海外服中,设定为夏侯惇的养女,继承了夏侯紫萼的血婆娑,之后“夏侯紫萼”这个名字就被隐匿于历史之中,而“夏侯子萼”则成为了血婆娑的首领“血蔷薇”的固定名号。', + zhangwei:'张葳,游卡桌游《三国杀阵面对决》中虚构的人物。在《阵面对决》中,设定为被夏侯子萼救下后加入的血婆娑成员。在海外服中,设定为张奂的养女,张奂为宦官迫害时与其失散,为神秘女子所救并学得武艺,后与夏侯紫萼一起建立血婆娑。在李儒分成时为了保护百姓而牺牲。', nashime:'难升米(なしめ,或なんしょうまい)是倭国大夫。景初二年六月,受女王卑弥呼之命,与都市牛利出使魏国,被魏国拜为率善中郎将。', jiachong:'贾充(217年—282年),字公闾,平阳襄陵(今山西襄汾)人,三国曹魏至西晋时期大臣,曹魏豫州刺史贾逵之子。西晋王朝的开国元勋。出身平阳贾氏。曾参与镇压淮南二叛和弑杀魏帝曹髦,因此深得司马氏信任,其女儿贾褒(一名荃)及贾南风分别嫁予司马炎弟司马攸及次子司马衷,与司马氏结为姻亲,地位显赫。晋朝建立后,转任车骑将军、散骑常侍、尚书仆射,后升任司空、太尉等要职。更封鲁郡公。咸宁末,为使持节、假黄钺、大都督征讨吴国。吴国平定后,增邑八千户。太康三年(282年),贾充去世。西晋朝廷追赠他为太宰,礼官议谥曰荒,司马炎不采纳,改谥为武。有集五卷。', duosidawang:'朵思大王是《三国演义》中人物,南蛮秃龙洞的元帅,孟获弟弟孟优的朋友,据说是南蛮第一智者。', @@ -298,9 +298,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ selectTarget:[1,3], multitarget:true, multiline:true, + group:'twdanlie_add', content:function(){ 'step 0' - player.addTempSkill('twdanlie_effect'); player.chooseToCompare(targets).setContent('chooseToCompareMeanwhile'); 'step 1' if(result.winner&&result.winner==player){ @@ -325,18 +325,26 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, subSkill:{ - effect:{ - charlotte:true, - trigger:{player:'compare'}, + add:{ + audio:'twdanlie', + trigger:{player:'compare',target:'compare'}, filter:function(event,player){ - return event.getParent().name=='twdanlie'&&!event.iwhile&&player.isDamaged(); + if(!player.isDamaged()) return false; + if(player!=event.target&&event.iwhile) return false; + return true; }, forced:true, - popup:false, + locked:false, content:function(){ var num=player.getDamagedHp(); - trigger.num1+=num; - if(trigger.num1>13) trigger.num1=13; + 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; + } game.log(player,'的拼点牌点数+',num); }, }, @@ -500,7 +508,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ subSkill:{ effect:{ charlotte:true, - trigger:{player:'useCard'}, + trigger:{player:'useCard1'}, filter:function(event,player){ return get.type(event.card)=='basic'||get.type(event.card)=='trick'; }, @@ -514,7 +522,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ name:trigger.card.name, isCard:true, }; - var targets=trigger.targets.filter(i=>i.isIn()); + var targets=trigger.targets.filter(i=>i.isIn()&&player.canUse(card,i,false)); if(targets.length) player.useCard(card,targets,false); } }); @@ -531,50 +539,65 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 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(){ 'step 0' - var list=lib.inpile.filter(name=>{ - var type=get.type2(name); - if(type!='basic'&&type!='trick') return false; - return !player.getStorage('twshenyi').includes(name); + 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)+'###选择一个牌名,从牌堆中将此一张此牌名的牌称为“侠义”置于武将牌上',[list,'vcard']]; + var dialog=[`###${get.prompt('twshenyi',trigger.player)}###
从牌堆中将一张牌作为“侠义”置于武将牌上${player!=trigger.player&&player.countCards('h')?',然后将所有手牌交给其':''}
`,[list,'vcard']]; player.chooseButton(dialog).set('ai',function(button){ var trigger=_status.event.getTrigger(); var player=_status.event.player,name=button.link[2]; if(get.attitude(player,trigger.player)<=0) return 0; if(!get.cardPile2(card=>card.name==name)) return 0; - return get.value({name:name}); + var value=get.value({name:name}); + if(['tao','jiu','caochuan','wuxie'].includes(name)&&get.event().getRand()>0.4) return value*2; + return value; }); 'step 1' if(result.bool){ - var name=result.links[0][2]; + var name=result.links[0][2],nature=result.links[0][3]; + var cardx={name:name,nature:nature}; player.logSkill('twshenyi',trigger.player); - player.popup(name); + player.popup(cardx); player.markAuto('twshenyi',[name]); - game.log(player,'声明了','#y'+get.translation(name)); - var card=get.cardPile2(card=>card.name==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{ player.chat('无牌可得?!'); game.log('但是牌堆中已经没有','#y'+get.translation(name),'了!'); } if(trigger.player!=player&&player.countCards('h')){ + game.delayex(); var skill='twshenyi_'+player.playerid; - if(!lib.skill[skill]){ - lib.skill[skill]={charlotte:true}; - lib.translate[skill]='义·'+get.translation(player.name); - } + game.broadcastAll(lib.skill.twshenyi.createGainTag,skill,player.name); + game.addVideo('skill',player,['twshenyi',[skill,player.name]]); player.give(player.getCards('h'),trigger.player).gaintag.add(skill); player.addSkill('twshenyi_draw'); } } 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); + } + 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:'侠义', @@ -598,56 +621,31 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return game.hasPlayer(target=>{ var evt=event.getl(target); 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].contains(skill)) return true; - } - return false; + for(let i in evt.gaintag_map){ + if(evt.gaintag_map[i].includes(skill)) return true; } - return target.hasHistory('lose',function(evt){ - if(event!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].contains(skill)) return true; - } - return false; - }); + 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; - if(trigger.name=='lose'){ - for(var i in trigger.gaintag_map){ - if(trigger.gaintag_map[i].contains(skill)) return true; - } - return false; + for(var i in evt.gaintag_map){ + if(evt.gaintag_map[i].includes(skill)) numx++; } - return target.hasHistory('lose',function(evt){ - if(trigger!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].contains(skill)) return true; - } - return false; - }); - }),num=0; - targets.forEach(target=>{ - var cards=trigger.getl(target).hs; - if(trigger.name=='lose'){ - for(var i in trigger.gaintag_map){ - if(trigger.gaintag_map[i].contains(skill)) num++; - } - } - else target.getHistory('lose',function(evt){ - if(trigger!=evt.getParent()) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].contains(skill)) num++; - } - }); + if(numx>0) return num+=numx; + return false; }); - if(num>0) player.draw(num); + if(num>0){ + player.logSkill('twshenyi_draw',targets); + player.draw(num); + } }, }, }, @@ -659,23 +657,29 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 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)); }, - prompt2:function(event,player){ - return '依次使用武将牌上的“侠义”牌,回合结束时弃置所有手牌并将失去X点体力(X为你的体力值-1且X至少为1)'; - }, + direct:true, content:function*(event,map){ var player=map.player; - while(player.getExpansions('twshenyi').some(card=>player.hasValueTarget(card))){ - var result=yield player.chooseButton(['兴汉:请选择其中的一张牌使用',player.getExpansions('twshenyi').filter(card=>player.hasValueTarget(card))]).set('ai',function(button){ - return _status.event.player.getUseValue(button.link); - }); - if(result.bool){ - player.chooseToUse(true,result.links[0],false); - } + 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); } player.when('phaseEnd').then(()=>{ - if(player.countCards('h')) player.discard(player.getCards('h')); + if(player.countCards('h')) player.chooseToDiscard(player.countCards('h'),true); var num=Math.max(1,player.getHp()-1); player.loseHp(num); }); @@ -685,17 +689,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ init:{ audio:'twxinghan', trigger:{ - player:['loseEnd','dying','dyingAfter'], + player:['loseEnd','dying','die','dyingAfter'], global:['equipEnd','addJudgeEnd','gainEnd','loseAsyncEnd','addToExpansionEnd'], }, filter:function(event,player){ - return (player.getExpansions('twshenyi').length&&(!player.countCards('h')||player.isDying()))^player.hasSkill('twxinghan_in'); + return (player.getExpansions('twshenyi').length&&event.name!='die'&&(!player.countCards('h')||player.isDying()))^player.hasSkill('twxinghan_in'); }, forced:true, firstDo:true, silent:true, + forceDie:true, content:function(){ - if(player.getExpansions('twshenyi').length&&(!player.countCards('h')||player.isDying())){ + if(player.getExpansions('twshenyi').length&&trigger.name!='die'&&(!player.countCards('h')||player.isDying())){ var cards=player.getExpansions('twshenyi'); var cardsx=cards.map(card=>{ var cardx=ui.create.card(); @@ -15211,7 +15216,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ xia_xiahoudun:'侠夏侯惇', xia_xiahoudun_prefix:'侠', twdanlie:'胆烈', - twdanlie_info:'出牌阶段限一次,你可以与至多三名其他角色同时拼点,且你此次的拼点牌点数+X(X为你已损失的体力值)。若你赢,你对这些角色各造成1点伤害;若你没赢,你失去1点体力。', + twdanlie_info:'①出牌阶段限一次。你可以与至多三名其他角色共同拼点。若你赢,你对没赢的角色依次造成1点伤害;若你没赢,你失去1点体力。②你的拼点牌点数+X(X为你已损失的体力值)。', xia_zhangwei:'张葳', twhuzhong:'护众', twhuzhong_info:'当你于出牌阶段使用无属性【杀】指定唯一目标角色时,你可以选择一项:①弃置一张手牌,然后你可以为此牌额外选择一个目标;②令其弃置一张手牌,此牌结算完毕后,若此牌造成过伤害,则你摸一张牌且本阶段可以额外使用一张【杀】,否则其对你造成1点伤害。', @@ -15223,9 +15228,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ xia_liubei:'侠刘备', xia_liubei_prefix:'侠', twshenyi:'伸义', - twshenyi_info:'每回合限一次,当你或你攻击范围内的一名角色受到伤害后,你可以声明一个基本牌或锦囊牌的牌名(每种牌名限一次),然后从牌堆中将一张同名牌称为“侠义”置于武将牌上,然后若受伤角色不为你,则你将所有手牌交给其,且当其失去一张你以此法交给其的牌后,你摸一张牌。', + twshenyi_info:'每回合限一次。当你或你攻击范围内的一名角色于一回合内首次受到伤害后,你可以声明一种基本牌或锦囊牌(每种牌名限一次),然后从牌堆中将一张同名牌称为“侠义”置于武将牌上。若受伤角色不为你,则你将所有手牌交给其,且当其失去一张你以此法交给其的牌后,你摸一张牌。', twxinghan:'兴汉', - twxinghan_info:'①当你没有手牌时或你处于濒死状态时,你可以如手牌般使用或打出你武将牌上的“侠义”牌。②准备阶段,若你武将牌上的“侠义”牌数大于场上的存活角色数,则你可以依次使用其中所有可以使用的牌,然后于回合结束时弃置所有手牌并失去X点体力(X为你的体力值-1且X至少为1)。', + twxinghan_info:'①当你没有手牌时或你处于濒死状态时,你可以如手牌般使用或打出“侠义”牌。②准备阶段,若“侠义”牌数大于存活角色数,则你可以依次使用其中所有可以使用的牌。然后你获得如下效果:回合结束时,你弃置所有手牌并失去X点体力(X为你的体力值-1且X至少为1)。', tw_mobile:'海外服·稀有专属', tw_yunchouzhi:'运筹帷幄·智', diff --git a/game/game.js b/game/game.js index 2510a72f9..c193bba6a 100644 --- a/game/game.js +++ b/game/game.js @@ -58261,6 +58261,26 @@ }, }; const get={ + /** + * 返回 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; + }, /** * 根据座次数n(从0开始)获取对应的“n+1号位”翻译 * @param {number} seat @@ -58518,7 +58538,7 @@ is:{ /** * 判断是否为进攻坐骑 - * @param {Card | VCard | Card[] | VCard[]} card + * @param {Card | VCard} card * @param {false | Player} [player] * @returns {boolean} */ @@ -58534,7 +58554,7 @@ }, /** * 判断是否为防御坐骑 - * @param {Card | VCard | Card[] | VCard[]} card + * @param {Card | VCard} card * @param {false | Player} [player] * @returns {boolean} */