diff --git a/audio/die/re_huaxiong.mp3 b/audio/die/re_huaxiong.mp3 index 1a76a4ac0..431f69b7a 100644 Binary files a/audio/die/re_huaxiong.mp3 and b/audio/die/re_huaxiong.mp3 differ diff --git a/audio/die/star_caoren.mp3 b/audio/die/star_caoren.mp3 new file mode 100644 index 000000000..8321eaee4 Binary files /dev/null and b/audio/die/star_caoren.mp3 differ diff --git a/audio/die/star_yuanshu.mp3 b/audio/die/star_yuanshu.mp3 new file mode 100644 index 000000000..96b97f6e5 Binary files /dev/null and b/audio/die/star_yuanshu.mp3 differ diff --git a/audio/skill/new_reyaowu1.mp3 b/audio/skill/new_reyaowu1.mp3 index c3827e1d4..88c39b1f8 100644 Binary files a/audio/skill/new_reyaowu1.mp3 and b/audio/skill/new_reyaowu1.mp3 differ diff --git a/audio/skill/new_reyaowu2.mp3 b/audio/skill/new_reyaowu2.mp3 index 01c5f5e63..ccc92d47e 100644 Binary files a/audio/skill/new_reyaowu2.mp3 and b/audio/skill/new_reyaowu2.mp3 differ diff --git a/audio/skill/starcanxi1.mp3 b/audio/skill/starcanxi1.mp3 new file mode 100644 index 000000000..09c939bc0 Binary files /dev/null and b/audio/skill/starcanxi1.mp3 differ diff --git a/audio/skill/starcanxi2.mp3 b/audio/skill/starcanxi2.mp3 new file mode 100644 index 000000000..cadb37671 Binary files /dev/null and b/audio/skill/starcanxi2.mp3 differ diff --git a/audio/skill/starlifeng1.mp3 b/audio/skill/starlifeng1.mp3 new file mode 100644 index 000000000..eb0251d42 Binary files /dev/null and b/audio/skill/starlifeng1.mp3 differ diff --git a/audio/skill/starlifeng2.mp3 b/audio/skill/starlifeng2.mp3 new file mode 100644 index 000000000..5655e897f Binary files /dev/null and b/audio/skill/starlifeng2.mp3 differ diff --git a/audio/skill/starpizhi1.mp3 b/audio/skill/starpizhi1.mp3 new file mode 100644 index 000000000..aac8f0dae Binary files /dev/null and b/audio/skill/starpizhi1.mp3 differ diff --git a/audio/skill/starpizhi2.mp3 b/audio/skill/starpizhi2.mp3 new file mode 100644 index 000000000..7b5ea337f Binary files /dev/null and b/audio/skill/starpizhi2.mp3 differ diff --git a/audio/skill/starsujun1.mp3 b/audio/skill/starsujun1.mp3 new file mode 100644 index 000000000..144bd5f9b Binary files /dev/null and b/audio/skill/starsujun1.mp3 differ diff --git a/audio/skill/starsujun2.mp3 b/audio/skill/starsujun2.mp3 new file mode 100644 index 000000000..8e8e54039 Binary files /dev/null and b/audio/skill/starsujun2.mp3 differ diff --git a/audio/skill/starzhonggu1.mp3 b/audio/skill/starzhonggu1.mp3 new file mode 100644 index 000000000..5cb768697 Binary files /dev/null and b/audio/skill/starzhonggu1.mp3 differ diff --git a/audio/skill/starzhonggu2.mp3 b/audio/skill/starzhonggu2.mp3 new file mode 100644 index 000000000..b6825aa47 Binary files /dev/null and b/audio/skill/starzhonggu2.mp3 differ diff --git a/audio/skill/wushuang_shen_lvbu1.mp3 b/audio/skill/wushuang_shen_lvbu1.mp3 new file mode 100644 index 000000000..6ed1b7505 Binary files /dev/null and b/audio/skill/wushuang_shen_lvbu1.mp3 differ diff --git a/audio/skill/wushuang_shen_lvbu2.mp3 b/audio/skill/wushuang_shen_lvbu2.mp3 new file mode 100644 index 000000000..bd7ab7805 Binary files /dev/null and b/audio/skill/wushuang_shen_lvbu2.mp3 differ diff --git a/character/extra.js b/character/extra.js index 4993cce83..0755537de 100755 --- a/character/extra.js +++ b/character/extra.js @@ -4670,7 +4670,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ enable:'phaseUse', derivation:'wushuang', filter:function(event,player){ - return player.countMark('baonu')>=2; + return player.countMark('baonu')>=2&&game.hasPlayer(target=>lib.skill.ol_wuqian.filterTarget(null,player,target)); }, filterTarget:function(card,player,target){ return target!=player&&!target.hasSkill('ol_wuqian_targeted'); @@ -4678,29 +4678,42 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ player.removeMark('baonu',2); player.addTempSkill('wushuang'); - player.storage.ol_wuqian_target=target; - player.addTempSkill('ol_wuqian_target'); + player.popup('无双'); + game.log(player,'获得了技能','#g【无双】'); target.addTempSkill('ol_wuqian_targeted'); }, - subSkill:{ - equip:{ - ai:{ - unequip:true, - skillTagFilter:function(player,tag,arg){ - if(arg&&arg.target&&arg.target.hasSkill('ol_wuqian_targeted')) return true; - return false; - } - } - }, - targeted:{ai:{unequip2:true}}, - target:{ - mark:'character', - onremove:true, - intro:{ - content:'获得无双且$防具失效直到回合结束' + ai:{ + order:9, + result:{ + target:function(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}, + }, + ai:{ + ai:{ + unequip2:true, + skillTagFilter:function(player){ + if(!_status.baonuCheck) return false; + }, + }, + }, + }, }, wumou:{ audio:2, diff --git a/character/huicui.js b/character/huicui.js index 8c5d15c1c..4c3814d5f 100644 --- a/character/huicui.js +++ b/character/huicui.js @@ -4,6 +4,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ name:'huicui', connect:true, character:{ + dc_sunchen:['male','wu',4,['dczigu','dczuowei'],['unseen']], dc_zhangmancheng:['male','qun',4,['dclvecheng','dczhongji']], yue_zhoufei:['female','wu',3,['dclingkong','dcxianshu']], dc_wuban:['male','shu',4,['dcyouzhan'],['clan:陈留吴氏','unseen']], diff --git a/character/rank.js b/character/rank.js index 09b861aa5..565661e96 100644 --- a/character/rank.js +++ b/character/rank.js @@ -124,6 +124,8 @@ window.noname_character_rank={ 'db_key_liyingxia', 'key_kiyu', 'jsrg_pangtong', + 'star_caoren', + 'clan_xunyou', ], a:[ 'diy_zaozhirenjun', @@ -339,6 +341,7 @@ window.noname_character_rank={ 'key_kotarou', 'key_kyou', 'key_tomoyo', + 'star_yuanshu', ], am:[ 'diy_caiwenji', @@ -976,6 +979,8 @@ window.noname_character_rank={ 'zhangyan', 'jsrg_huangzhong', 'jsrg_zhangchu', + 'ol_dingshangwan', + 'ol_liwan', ], b:[ 'diy_feishi', @@ -2023,6 +2028,9 @@ window.noname_character_rank={ 'key_kotomi', 'db_key_liyingxia', 'key_iriya', + 'star_caoren', + 'star_yuanshu', + 'clan_xunyou', ], rare:[ 'luoxian', @@ -2486,6 +2494,8 @@ window.noname_character_rank={ 'ol_wenqin', 'clan_wanghun', 'yue_zhoufei', + 'ol_dingshangwan', + 'ol_liwan', ], junk:[ 'sunshao', diff --git a/character/sp.js b/character/sp.js index 26b77f536..ce0f96284 100755 --- a/character/sp.js +++ b/character/sp.js @@ -1574,7 +1574,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ chooseButton:{ dialog:function(event,player){ return ui.create.dialog( - '###缚豕###
重铸任意“缚豕”牌,视为使用一张【杀】并执行等量项
', + '###缚豕###
将任意“缚豕”牌置入弃牌堆,视为使用一张【杀】并执行等量项
', player.getExpansions('olfushi'), [['额外目标','伤害-1','伤害+1'],'tdnodes'], 'hidden' @@ -1686,7 +1686,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ delete event.result.skill; event.result.card=new lib.element.VCard(lib.skill.olfushi_wusheng_backup.viewAs); event.result.cards=[]; - player.recast(cards); + player.loseToDiscardpile(cards); event.result.card.storage.olfushi_buff=controls; player.addTempSkill('olfushi_buff'); } @@ -1695,7 +1695,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ prompt:function(links,player){ let controls=links.filter(button=>typeof button=='string'); if(!controls.length) controls=['额外目标','伤害-1','伤害+1']; - return `选择【杀】的目标(${controls.join('、')})`; + return `请选择【杀】的目标(${controls.join('、')})`; } }, ai:{ @@ -26454,7 +26454,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ skill_feiyi_B_info:'每回合每项限一次,当你的手牌数变为1后,你可以展示此唯一手牌A并摸一张牌,然后你选择一项:①本回合使用点数大于A的点数的牌额外结算一次;②本回合使用点数小于A的点数的牌额外结算一次。', lvboshe:'吕伯奢', olfushi:'缚豕', - olfushi_info:'①一名角色使用【杀】结算结束后,若你至其的距离不大于1,你将此【杀】对应的所有实体牌置于武将牌上。②当你需要使用一张【杀】时,你可以重铸任意张“缚豕”牌,视为使用一张【杀】并选择X项(X为你以此法重铸的牌数且至多为3):1.你为此【杀】额外指定一个目标;2.你选择此【杀】的一个目标角色,此牌对其造成的伤害-1;3.你选择此【杀】的一个目标角色,此【杀】对其造成的伤害+1。当此【杀】指定最后一个目标后,若此牌被选择的效果选项相邻且此牌的目标角色座位连续,则此【杀】不计入次数限制。', + olfushi_info:'①一名角色使用【杀】结算结束后,若你至其的距离不大于1,你将此【杀】对应的所有实体牌置于武将牌上。②当你需要使用一张【杀】时,你可以将任意张“缚豕”牌置入弃牌堆,视为使用一张【杀】并选择X项(X为你以此法重铸的牌数且至多为3):1.你为此【杀】额外指定一个目标;2.你选择此【杀】的一个目标角色,此牌对其造成的伤害-1;3.你选择此【杀】的一个目标角色,此【杀】对其造成的伤害+1。当此【杀】指定最后一个目标后,若此牌被选择的效果选项相邻且此牌的目标角色座位连续,则此【杀】不计入次数限制。', oldongdao:'东道', oldongdao_info:'农民的回合结束时:阴,你可以令地主进行一个额外回合;阳,其可以进行一个额外回合。', zhangyan:'张燕', diff --git a/character/sp2.js b/character/sp2.js index 69e5f4095..facb1f613 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:{ + star_yuanshu:['male','qun',4,['starcanxi','starpizhi','starzhonggu'],['zhu']], star_caoren:['male','wei',4,['starsujun','starlifeng']], dc_jikang:['male','wei',3,['new_qingxian','dcjuexiang']], dc_jsp_guanyu:['male','wei',4,['new_rewusheng','dcdanji']], @@ -108,11 +109,209 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 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'], + sp_star:['star_caoren','star_yuanshu'], sp_decade:['caobuxing','re_maliang','xin_baosanniang','dc_jikang'], } }, skill:{ + //星袁术 + 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; + }, + 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)); + } + '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]; + player.popup(skill); + game.log(player,'选择了','#g'+result.links[0],'、','#y'+get.translation(skill)); + player.addTempSkill(skill,'roundStart'); + player.markAuto(skill,[group]); + } + }, + create:function(group,player){ + if(!lib.skill['starcanxi_'+group]){ + lib.skill['starcanxi_'+group]={ + mark:true, + charlotte:true, + onremove:function(player){ + player.addMark('starpizhi',1,false); + }, + intro:{content:'玉玺的一角'}, + }; + lib.translate['starcanxi_'+group]='残玺·'+get.translation(group+'2'); + lib.skill['starcanxi_'+group].marktext=get.translation(group); + lib.translate['starcanxi_'+group+'_bg']=get.translation(group); + } + player.addSkill('starcanxi_'+group); + }, + 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(){ + trigger.num++; + }, + 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; + }, + 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; + }, + 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; + }, + }, + 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'); + }, + }, + }, + }, + starpizhi:{ + audio:2, + trigger:{player:'phaseEnd',global:'die'}, + filter:function(event,player){ + if(event.name=='phase') return player.hasMark('starpizhi'); + 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); + player.removeSkill(skills); + } + 'step 1' + player.draw(player.countMark('starpizhi')); + }, + intro:{content:'已失去#个“玺角”'}, + ai:{combo:'starcanxi'}, + }, + 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; + }, + }, //星曹仁 starsujun:{ audio:2, @@ -139,7 +338,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ enable:'chooseToUse', filter:function(event,player){ if(!event.filterCard({name:'sha'},player,event)&&!event.filterCard({name:'wuxie'},player,event)) return false; - return player.countCards('h',card=>{ + return player.countCards('hs',card=>{ return !player.getStorage('starlifeng_count').contains(get.color(card,player))||_status.connectMode; }); }, @@ -165,7 +364,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ event.getParent().addCount=false; }, popname:true, - position:'h', viewAs:{ name:links[0][2], }, @@ -185,7 +383,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, hiddenCard:function(player,name){ - if(name=='wuxie') return player.countCards('h',card=>{ + if(name=='wuxie') return player.countCards('hs',card=>{ return !player.getStorage('starlifeng_count').contains(get.color(card,player))||_status.connectMode; }); }, @@ -193,7 +391,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ respondSha:true, skillTagFilter:function(player,tag,arg){ if(arg=='respond') return false; - if(!player.countCards('h',card=>{ + if(!player.countCards('hs',card=>{ return !player.getStorage('starlifeng_count').contains(get.color(card,player))||_status.connectMode; })) return false; }, @@ -10606,6 +10804,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){ starsujun_info:'当你使用一张牌时,若你手牌中的基本牌和非基本牌的牌数相等,你可以摸两张牌。', starlifeng:'砺锋', starlifeng_info:'你可以将一张本回合未有角色使用过的颜色的手牌当做不计入次数的【杀】或【无懈可击】使用。', + star_yuanshu:'星袁术', + star_yuanshu_prefix:'星', + starcanxi:'残玺', + starcanxi_wangsheng:'妄生', + starcanxi_xiangsi:'向死', + starcanxi_cancel:'向死', + starcanxi_info:'锁定技。游戏开始时,你获得场上所有角色的势力对应的“玺角”标记,然后选择一个“玺角”对应势力并选择以下一项;一轮开始时,你选择一个“玺角”对应势力并选择以下一项:①妄生:本轮被选择势力角色每回合首次造成的伤害+1且计算与其他角色间的距离-1;②向死:本轮其他被选择势力角色每回合首次回复体力后失去1点体力且每回合对你使用的第一张牌无效。', + starpizhi:'圮秩', + starpizhi_info:'锁定技。①一名角色死亡后,若你拥有该角色对应的“玺角”标记,你失去之并摸X张牌。②结束阶段,你摸X张牌。(X为你本局游戏失去的“玺角”标记数)', + starzhonggu:'冢骨', + starzhonggu_info:'主公技,锁定技。摸牌阶段,若游戏轮数大于等于场上的群势力角色数,则你额外摸两张牌,否则你少摸一张牌。', sp_whlw:"文和乱武", sp_zlzy:"逐鹿中原", diff --git a/character/tw.js b/character/tw.js index 90a6f4b75..2b540c0f6 100644 --- a/character/tw.js +++ b/character/tw.js @@ -12,7 +12,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 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_xushu','xia_wangyue','xia_liyàn','xia_tongyuan','xia_lusu','xia_dianwei','xia_zhaoe','xia_xiahouzie'], + tw_swordsman:['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'], @@ -20,6 +20,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, character:{ + 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']], @@ -123,6 +127,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ kaisa:["male","western",4,["zhengfu"]], }, characterIntro:{ + xiahousone:'三国杀集换式卡牌游戏《阵面对决》中的裂土系列卡牌。游卡桌游官方原创的三国时期女性角色。', + zhangwei:'三国杀集换式卡牌游戏《阵面对决》中的帝畿系列卡牌。游卡桌游官方原创的三国时期女性角色。', nashime:'难升米(なしめ,或なんしょうまい)是倭国大夫。景初二年六月,受女王卑弥呼之命,与都市牛利出使魏国,被魏国拜为率善中郎将。', jiachong:'贾充(217年—282年),字公闾,平阳襄陵(今山西襄汾)人,三国曹魏至西晋时期大臣,曹魏豫州刺史贾逵之子。西晋王朝的开国元勋。出身平阳贾氏。曾参与镇压淮南二叛和弑杀魏帝曹髦,因此深得司马氏信任,其女儿贾褒(一名荃)及贾南风分别嫁予司马炎弟司马攸及次子司马衷,与司马氏结为姻亲,地位显赫。晋朝建立后,转任车骑将军、散骑常侍、尚书仆射,后升任司空、太尉等要职。更封鲁郡公。咸宁末,为使持节、假黄钺、大都督征讨吴国。吴国平定后,增邑八千户。太康三年(282年),贾充去世。西晋朝廷追赠他为太宰,礼官议谥曰荒,司马炎不采纳,改谥为武。有集五卷。', duosidawang:'朵思大王是《三国演义》中人物,南蛮秃龙洞的元帅,孟获弟弟孟优的朋友,据说是南蛮第一智者。', @@ -278,6 +284,510 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, skill:{ + //夏侯惇 + twdanlie:{ + audio:2, + enable:'phaseUse', + filter:function(event,player){ + return game.hasPlayer(target=>player.canCompare(target)); + }, + filterTarget:function(card,player,target){ + return player.canCompare(target); + }, + usable:1, + selectTarget:[1,3], + multitarget:true, + multiline:true, + content:function(){ + 'step 0' + player.addTempSkill('twdanlie_effect'); + player.chooseToCompare(targets).setContent('chooseToCompareMeanwhile'); + 'step 1' + if(result.winner&&result.winner==player){ + player.line(targets); + 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); + return 0; + }, + }, + }, + subSkill:{ + effect:{ + charlotte:true, + trigger:{player:'compare'}, + filter:function(event,player){ + return event.getParent().name=='twdanlie'&&!event.iwhile&&player.isDamaged(); + }, + forced:true, + popup:false, + content:function(){ + var num=player.getDamagedHp(); + trigger.num1+=num; + if(trigger.num1>13) trigger.num1=13; + 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()&&((player.countCards('h')&&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=[ + '弃置一张手牌,令此【杀】可以额外指定一个目标', + '令其弃置一张手牌,若此【杀】造成伤害,则你摸一张牌且本阶段可以额外使用一张【杀】;若此【杀】未造成伤害,你受到其对你造成的1点伤害', + ]; + if(target.countCards('h')) list.unshift('其弃置'); + else choiceList[1]=''+choiceList[1]+''; + if(player.countCards('h')&&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.contains('其弃置')&&_status.event.goon) return '其弃置'; + if(controls.contains('你弃置')){ + 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.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; + }()); + 'step 1' + if(result.control!='cancel2'){ + player.logSkill('twhuzhong',target); + if(result.control=='其弃置'){ + target.chooseToDiscard('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('shenzhu_more','phaseUseAfter'); + player.addMark('shenzhu_more',1,false); + } + else{ + target.line(player); + player.damage(1,target); + } + }).vars({target:target}); + event.finish(); + } + else{ + player.chooseToDiscard('h',true); + 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); + }); + } + } + else event.finish(); + 'step 2' + if(result.bool){ + player.line(result.targets); + trigger.getParent().targets.addArray(result.targets); + game.log(result.targets,'成为了',trigger.card,'的额外目标'); + } + }, + }, + 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'){ + 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++; + }, + }, + //夏侯子萼 + //差点和夏侯紫萼搞混 + 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').contains(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); + } + player.markAuto('twchengxi_used',[target]); + player.draw(); + '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); + } + }, + 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:'useCard'}, + 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()); + if(targets.length) player.useCard(card,targets,false); + } + }); + }, + mark:true, + marktext:'袭', + intro:{content:'使用的下一张基本牌或非延时锦囊牌结算完毕后视为对相同目标再使用一张无次数限制的同名牌'}, + }, + }, + }, + //侠刘备 + twshenyi:{ + audio:2, + trigger:{global:'damageEnd'}, + filter:function(event,player){ + if(!event.player.isIn()) 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 dialog=['###'+get.prompt('twshenyi',trigger.player)+'###选择一个牌名,从牌堆中将此一张此牌名的牌称为“侠义”置于武将牌上',[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}); + }); + 'step 1' + if(result.bool){ + var name=result.links[0][2]; + player.logSkill('twshenyi',trigger.player); + player.popup(name); + player.markAuto('twshenyi',[name]); + game.log(player,'声明了','#y'+get.translation(name)); + var card=get.cardPile2(card=>card.name==name); + 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')){ + var skill='twshenyi_'+player.playerid; + if(!lib.skill[skill]){ + lib.skill[skill]={charlotte:true}; + lib.translate[skill]='义·'+get.translation(player.name); + } + player.give(player.getCards('h'),trigger.player).gaintag.add(skill); + player.addSkill('twshenyi_draw'); + } + } + else player.storage.counttrigger.twshenyi--; + }, + marktext:'义', + intro:{ + name:'侠义', + content:'expansion', + markcount:'expansion', + }, + 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'], + }, + 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; + if(event.name=='lose'){ + for(var i in event.gaintag_map){ + if(event.gaintag_map[i].contains(skill)) return true; + } + return false; + } + 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; + }); + }); + }, + forced:true, + content:function(){ + var skill='twshenyi_'+player.playerid; + var targets=game.filterPlayer(target=>{ + var evt=trigger.getl(target); + 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; + } + 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(num>0) player.draw(num); + }, + }, + }, + }, + twxinghan:{ + audio:2, + trigger:{player:'phaseZhunbeiBegin'}, + filter:function(event,player){ + return player.getExpansions('twshenyi').length>game.countPlayer(); + }, + check:function(event,player){ + return player.getExpansions('twshenyi').some(card=>player.hasValueTarget(card)); + }, + prompt2:function(event,player){ + return '依次使用武将牌上的“侠义”牌,回合结束时弃置所有手牌并将失去X点体力(X为你的体力值-1且X至少为1)'; + }, + 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); + } + } + player.when('phaseEnd').then(()=>{ + if(player.countCards('h')) player.discard(player.getCards('h')); + var num=Math.max(1,player.getHp()-1); + player.loseHp(num); + }); + }, + group:'twxinghan_init', + subSkill:{ + init:{ + audio:'twxinghan', + trigger:{ + player:['loseEnd','dying','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'); + }, + forced:true, + firstDo:true, + silent:true, + content:function(){ + if(player.getExpansions('twshenyi').length&&(!player.countCards('h')||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; + return cardx; + }); + player.directgains(cardsx,null,'twxinghan'); + player.addSkill('twxinghan_in'); + } + else player.removeSkill('twxinghan_in'); + }, + }, + in:{ + charlotte:true, + audio:'twxinghan', + trigger:{player:'addToExpansionEnd'}, + filter:function(event,player){ + return event.gaintag.contains('twshenyi'); + }, + forced:true, + locked:false, + silent:true, + content:function(){ + 'step 0' + var cards2=player.getCards('s',card=>card.hasGaintag('twxinghan')); + 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(); + cardx.init(get.cardInfo(card)); + cardx._cardid=card.cardid; + return cardx; + }); + player.directgains(cardsx,null,'twxinghan'); + }, + onremove:function(player){ + var cards2=player.getCards('s',card=>card.hasGaintag('twxinghan')); + 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(); + }, + group:'twxinghan_use', + }, + use:{ + charlotte:true, + trigger:{player:['useCardBefore','respondBefore']}, + filter:function(event,player){ + var cards=player.getCards('s',card=>card.hasGaintag('twxinghan')&&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')).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); + } + cards3.forEach(i=>i.delete()); + if(player==game.me) ui.updatehl(); + }, + }, + }, + }, //张纮 twquanqian:{ audio:2, @@ -14698,6 +15208,24 @@ game.import('character',function(lib,game,ui,get,ai,_status){ kaisa:"凯撒", zhengfu:"征服", zhengfu_info:"当你使用【杀】指定目标时,你可以选择一种牌的类别,然后除非目标角色交给你一种该类别的牌,否则其不能闪避此【杀】。", + xia_xiahoudun:'侠夏侯惇', + xia_xiahoudun_prefix:'侠', + twdanlie:'胆烈', + twdanlie_info:'出牌阶段限一次,你可以与至多三名其他角色同时拼点,且你此次的拼点牌点数+X(X为你已损失的体力值)。若你赢,你对这些角色各造成1点伤害;若你没赢,你失去1点体力。', + xia_zhangwei:'张葳', + twhuzhong:'护众', + twhuzhong_info:'当你于出牌阶段使用无属性【杀】指定唯一目标角色时,你可以选择一项:①弃置一张手牌,然后你可以为此牌额外选择一个目标;②令其弃置一张手牌,此牌结算完毕后,若此牌造成过伤害,则你摸一张牌且本阶段可以额外使用一张【杀】,否则其对你造成1点伤害。', + 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)。', tw_mobile:'海外服·稀有专属', tw_yunchouzhi:'运筹帷幄·智', diff --git a/character/yijiang.js b/character/yijiang.js index d135fe7f5..6e99a454a 100755 --- a/character/yijiang.js +++ b/character/yijiang.js @@ -415,21 +415,21 @@ game.import('character',function(lib,game,ui,get,ai,_status){ subSkill:{ effect:{ audio:'qingbei', - trigger:{ - player:'useCardAfter', - }, - forced:true, + trigger:{player:'useCardAfter'}, charlotte:true, onremove:true, filter:function(event,player){ + if(!lib.suit.includes(get.suit(event.card))) return false; return player.getStorage('qingbei_effect').length; }, + direct:true, + firstDo:true, content:function(){ player.draw(player.getStorage('qingbei_effect').length); }, mark:true, intro:{ - content:(storage)=>`本轮内不能使用${get.translation(storage)}花色的牌,且使用牌后摸${get.cnNumber(storage.length)}张牌`, + content:(storage)=>`本轮内不能使用${get.translation(storage)}花色的牌,且使用一张有花色的牌后摸${get.cnNumber(storage.length)}张牌`, }, mod:{ cardEnabled:function(card,player){ @@ -14684,7 +14684,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ cuguo_info:'锁定技。当你于一回合使用牌首次被抵消后,你弃置一张牌,视为对此牌的目标角色使用一张该被抵消的牌。此牌结算结束后,若此牌被抵消,你失去1点体力。', chenshi:'陈式', qingbei:'擎北', - qingbei_info:'一轮游戏开始时,你可以选择任意种花色,你不能于本轮内使用这些花色的牌。然后当你于本轮使用牌结算结束后,你摸等同于你上一次〖擎北〗选择过的花色数的牌。', + qingbei_info:'一轮游戏开始时,你可以选择任意种花色,你不能于本轮内使用这些花色的牌。然后当你于本轮使用一张有花色的牌结算结束后,你摸等同于你上一次〖擎北〗选择过的花色数的牌。', feiyao:'费曜', zhenfeng:'镇锋', zhenfeng_info:'每回合限一次。当其他角色于其回合内使用牌时,若其手牌数不大于其体力值,你可以猜测其手牌中与此牌类别相同的牌数。若你猜对,你摸X张牌并视为对其使用一张【杀】(X为你连续猜对的次数且至多为5);若你猜错且差值大于1,其视为对你使用一张【杀】。', diff --git a/image/character/star_yuanshu.jpg b/image/character/star_yuanshu.jpg new file mode 100644 index 000000000..5886c07f9 Binary files /dev/null and b/image/character/star_yuanshu.jpg differ