diff --git a/card/standard.js b/card/standard.js
index 850299e31..e979cc202 100644
--- a/card/standard.js
+++ b/card/standard.js
@@ -184,8 +184,8 @@ game.import('card',function(lib,game,ui,get,ai,_status){
}
"step 3"
if((!result||!result.bool||!result.result||result.result!='shaned')&&!event.unhurt){
- if (!event.directHit&&!event.directHit2&&lib.filter.cardEnabled(new lib.element.VCard('shan'), target, 'forceEnable')&&
- target.hasCard(()=>true,'hs')&&get.damageEffect(target,player,target)<0) target.addGaintag(target.getCards('hs'),'sha_notshan');
+ if (!event.directHit&&!event.directHit2&&lib.filter.cardEnabled(new lib.element.VCard({name:'shan'}), target, 'forceEnable')&&
+ target.countCards('hs')>0&&get.damageEffect(target,player,target)<0) target.addGaintag(target.getCards('hs'),'sha_notshan');
target.damage(get.nature(event.card));
event.result={bool:true}
event.trigger('shaDamage');
diff --git a/card/yongjian.js b/card/yongjian.js
index 18f63d18a..5e0a3e7e1 100644
--- a/card/yongjian.js
+++ b/card/yongjian.js
@@ -411,7 +411,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){
equipSkill:true,
forced:true,
trigger:{target:'gift'},
- filter:(event,player)=>event.target!=player,
+ filter:(event,player)=>event.player!=player,
logTarget:'player',
content:()=>{
trigger.deniedGift.add(trigger.card);
diff --git a/character/extra.js b/character/extra.js
index 256698cac..2b712a371 100755
--- a/character/extra.js
+++ b/character/extra.js
@@ -155,8 +155,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){
'虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。',
'鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。',
'熊:每回合限一次,当你受到伤害时,此伤害-1。',
- '猿:出牌阶段开始时,你选择一名角色,随机获得其装备区里的一张牌。',
- '鹤:出牌阶段开始时,你摸三张牌。',
+ '猿:当你获得此效果时,你选择一名其他角色,获得其装备区里的一张牌。',
+ '鹤:当你获得此效果时,你摸三张牌。',
],
updateMark:function(player){
var wuqinxi=player.storage.wuling_wuqinxi;
@@ -177,11 +177,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){
game.broadcastAll(function(player,curMark){
if(player.marks.wuling_wuqinxi) player.marks.wuling_wuqinxi.firstChild.innerHTML=curMark;
},player,curMark);
- if(curMark=='鹿'){
- player.logSkill('wuling_wuqinxi');
- player.recover();
- player.discard(player.getCards('j')).discarder=player;
- }
+ var next=game.createEvent('wuling_change');
+ next.player=player;
+ next.setContent('emptyEvent');
},
ai:{
order:7,
@@ -214,7 +212,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
},
trigger:{
source:'damageBegin1',
- player:['phaseZhunbeiBegin','damageBegin4','phaseUseBegin'],
+ player:['phaseZhunbeiBegin','damageBegin4','wuling_change'],
},
filter:function(event,player,name){
const wuqinxi=player.storage.wuling_wuqinxi&&player.storage.wuling_wuqinxi[0];
@@ -228,9 +226,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){
case 'damageBegin4':
return wuqinxi=='熊'&&!player.hasSkill('wuling_xiong');
default:
- if(wuqinxi=='鹤') return true;
- if(wuqinxi!='猿') return false;
- return game.hasPlayer(target=>target.countGainableCards(player,'e'));
+ switch(wuqinxi){
+ case '鹿':
+ return player.isDamaged()||player.countCards('j');
+ case '鹤':
+ return true;
+ case '猿':
+ return game.hasPlayer(target=>target!=playertarget.countGainableCards(player,'e'));
+ default:
+ return false;
+ }
+ break;
}
},
forced:true,
@@ -256,31 +262,38 @@ game.import('character',function(lib,game,ui,get,ai,_status){
event.finish();
break;
default:
- if(wuqinxi=='鹤'){
- player.draw(3);
- event.finish();
- }
- else{
- player.chooseTarget('五禽戏:获得一名角色装备区里的一张装备牌',function(card,player,target){
- return target.countGainableCards(player,'e');
- }).set('ai',function(target){
- var player=_status.event.player;
- var att=get.attitude(player,target),eff=0;
- target.getCards('e',function(card){
- var val=get.value(card,target);
- eff=Math.max(eff,-val*att);
+ switch(wuqinxi){
+ case '鹿':
+ player.recover();
+ player.discard(player.getCards('j')).discarder=player;
+ event.finish();
+ break;
+ case '鹤':
+ player.draw(3);
+ event.finish();
+ break;
+ case '猿':
+ player.chooseTarget('五禽戏:获得一名其他角色装备区里的一张装备牌',function(card,player,target){
+ return target!=player&&target.countGainableCards(player,'e');
+ }).set('ai',function(target){
+ var player=_status.event.player;
+ var att=get.attitude(player,target),eff=0;
+ target.getCards('e',function(card){
+ var val=get.value(card,target);
+ eff=Math.max(eff,-val*att);
+ });
+ return eff;
});
- return eff;
- });
+ break;
}
+ break;
}
}
'step 1'
if(result.bool){
var target=result.targets[0];
player.line(target,'green');
- var cards=target.getGainableCards(player,'e');
- player.gain(cards.randomGets(1),target,'give');
+ player.gainPlayerCard(target,'e',true);
}
},
ai:{
@@ -7014,11 +7027,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){
source:'damageSource'
},
filter:function(event,player){
- if(get.attitude(_status.event.player,event.player)>=0) return false;
if(player.storage.drlt_duorui.length) return false;
return event.player.isIn()&&_status.currentPhase==player;
},
check:function(event,player){
+ if(get.attitude(_status.event.player,event.player)>=0) return false;
if(player.hasEnabledSlot()&&!player.hasEnabledSlot(5)) return false;
return true;
},
@@ -8049,8 +8062,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){
'
虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。'+
'
鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。'+
'
熊:每回合限一次,当你受到伤害时,此伤害-1。'+
- '
猿:出牌阶段开始时,你选择一名角色,随机获得其装备区里的一张牌。'+
- '
鹤:出牌阶段开始时,你摸三张牌。',
+ '
猿:当你获得此效果时,你选择一名其他角色,获得其装备区里的一张牌。'+
+ '
鹤:当你获得此效果时,你摸三张牌。',
youyi:'游医',
youyi_info:'①弃牌阶段结束时,你可以将所有于此阶段弃置的牌置入仁区。②出牌阶段限一次。你可以将仁区的所有牌置入弃牌堆,令所有角色各回复1点体力。',
diff --git a/character/huicui.js b/character/huicui.js
index 204981408..82d577a32 100644
--- a/character/huicui.js
+++ b/character/huicui.js
@@ -107,7 +107,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
sp_jishi:['dc_jiben','zhenghun','dc_sunhanhua','liuchongluojun'],
sp_raoting:['dc_huanghao','dc_sunziliufang','dc_sunchen','dc_jiachong'],
sp_yijun:['gongsundu','mengyou'],
- sp_zhengyin:['yue_caiwenji','yue_zhoufei','yue_caiyong'],
+ sp_zhengyin:['yue_caiwenji','yue_zhoufei','yue_caiyong','yue_xiaoqiao'],
}
},
skill:{
@@ -658,7 +658,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
trigger:{global:'phaseEnd'},
forced:true,
filter:function(event,player){
- return player.getHistory('useCard').length>player.getHp();
+ return player.getHistory('useCard').length>player.getHp()||player.getHistory('gain').reduce((sum,evt)=>sum+evt.cards.length,0)>player.getHp();
},
content:function*(event,map){
const player=map.player;
@@ -1094,9 +1094,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){
trigger:{player:['gainAfter','loseAsyncAfter']},
forced:true,
filter:(event,player)=>{
- // if(player==_status.currentPhase) return false;
if(event.getParent('phaseDraw',true)) return false;
- const evt=player.getHistory('gain')[0];
+ const evt=player.getHistory('gain',i=>!i.getParent('phaseDraw',true))[0];
if(!evt) return false;
if(event.name=='gain'){
if(evt!=event||event.getlx===false) return false;
@@ -1109,8 +1108,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){
},
content:function(){
var hs=player.getCards('h'),cards=trigger.getg(player);
- var card=cards.filter(card=>hs.includes(card)).randomGet();
- player.addGaintag(card,'dclingkong_tag');
+ cards=cards.filter(card=>hs.includes(card));
+ player.addGaintag(cards,'dclingkong_tag');
game.delayx();
},
},
@@ -2254,7 +2253,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
logTarget:'player',
content:function(){
var num=trigger.player.countMark('dcshengdu');
- player.draw(num);
+ player.draw(num*trigger.cards.length);
trigger.player.removeMark('dcshengdu',num);
},
}
@@ -11093,6 +11092,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){
zhangchu:['zhangchu','jsrg_zhangchu'],
xianglang:['xianglang','mb_xianglang'],
chengui:['chengui','mb_chengui'],
+ liuyong:['liuyong','jsrg_liuyong'],
+ zhangxuan:['zhangxuan','jsrg_zhangxuan'],
+ gaoxiang:['gaoxiang','jsrg_gaoxiang'],
},
translate:{
re_panfeng:'潘凤',
@@ -11468,7 +11470,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
dcguangshi_info:'锁定技。准备阶段,若所有其他角色均有“信众”,你摸两张牌并失去1点体力。',
dongwan:'董绾',
dcshengdu:'生妒',
- dcshengdu_info:'回合开始时,你可以选择一名其他角色,令其获得1枚“生妒”标记。有“生妒”标记的角色于摸牌阶段得到牌后,你摸X张牌,然后其移去所有“生妒”标记(X为其拥有的“生妒”标记数)。',
+ dcshengdu_info:'回合开始时,你可以选择一名其他角色,令其获得1枚“生妒”标记。有“生妒”标记的角色于摸牌阶段得到牌后,你摸X张牌,然后其移去所有“生妒”标记(X为摸牌数乘以其拥有的“生妒”标记数)。',
dcjieling:'介绫',
dcjieling_info:'出牌阶段每种花色限一次,你可以将两张花色不同的手牌当无距离限制且无任何次数限制的【杀】使用。然后若此【杀】:造成了伤害,所有目标角色失去1点体力;未造成伤害,所有目标角色依次获得1枚“生妒”标记。',
yuanyin:'袁胤',
@@ -11514,7 +11516,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
yue_zhoufei_prefix:'乐',
dclingkong:'灵箜',
dclingkong_tag:'箜篌',
- dclingkong_info:'锁定技。①游戏开始时,你将所有手牌标记为“箜篌”。②你的“箜篌”牌不计入手牌上限。③当你于一回合内首次于摸牌阶段外得到牌后,系统随机将其中的一张牌标记为“箜篌”。',
+ dclingkong_info:'锁定技。①游戏开始时,你将所有手牌标记为“箜篌”。②你的“箜篌”牌不计入手牌上限。③当你于一回合内首次于摸牌阶段外得到牌后,你将这些牌标记为“箜篌”。',
dcxianshu:'贤淑',
dcxianshu_info:'出牌阶段,你可以将一张“箜篌”正面向上交给一名其他角色,然后你摸X张牌(X为你与其的体力值之差且至多为5)。若此牌为红色,且该角色的体力值不大于你,则其回复1点体力;若此牌为黑色,且该角色的体力值不小于你,则其失去1点体力。',
dc_zhangmancheng:'张曼成',
@@ -11531,7 +11533,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
dccaisi:'才思',
dccaisi_info:'当你于回合内/回合外使用基本牌结算结束后,若你本回合以此法得到的牌数小于你的体力上限,你可以从牌堆/弃牌堆随机获得一张非基本牌,然后本回合下次发动此技能获得的牌数+1。',
dczhuoli:'擢吏',
- dczhuoli_info:'锁定技。一名角色的回合结束时,若你本回合使用的牌数大于体力值,你加1点体力上限(不能超过存活角色数),回复1点体力。',
+ dczhuoli_info:'锁定技。一名角色的回合结束时,若你本回合使用或获得的牌数大于体力值,你加1点体力上限(不能超过存活角色数),回复1点体力。',
yue_caiyong:'乐蔡邕',
yue_caiyong_prefix:'乐',
dcjiaowei:'焦尾',
@@ -11552,9 +11554,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){
yue_xiaoqiao:'乐小乔',
yue_xiaoqiao_prefix:'乐',
dcqiqin:'绮琴',
- dcqiqin_info:'锁定技。①游戏开始时,你将所有手牌标记为“乐”。②你的“乐”牌不计入手牌上限。③准备阶段,你获得弃牌堆中所有你标记过的“乐”牌。',
+ dcqiqin_tag:'琴',
+ dcqiqin_info:'锁定技。①游戏开始时,你将所有手牌标记为“琴”。②你的“琴”牌不计入手牌上限。③准备阶段,你获得弃牌堆中所有你标记过的“琴”牌。',
dcweiwan:'媦婉',
- dcweiwan_info:'出牌阶段限一次,你可以弃置一张“乐”并获得一名其他角色区域内花色与此牌不相同的牌各一张,若你获得了:一张牌,其失去1点体力;两张牌,本回合你对其使用牌无距离和次数限制;三张牌,本回合你不能对其使用牌。',
+ dcweiwan_info:'出牌阶段限一次,你可以弃置一张“琴”并随机获得一名其他角色区域内花色与此牌不相同的牌各一张,若你获得了:一张牌,其失去1点体力;两张牌,本回合你对其使用牌无距离和次数限制;三张牌,本回合你不能对其使用牌。',
sp_baigei:'无双上将',
sp_caizijiaren:'才子佳人',
diff --git a/character/jsrg.js b/character/jsrg.js
index 3b785c45c..bad9c601e 100644
--- a/character/jsrg.js
+++ b/character/jsrg.js
@@ -8,6 +8,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
jiangshanrugu_qi:['jsrg_liuhong','jsrg_hejin','jsrg_sunjian','jsrg_huangfusong','jsrg_xushao','jsrg_dongbai','jsrg_qiaoxuan','jsrg_yangbiao','jsrg_kongrong','jsrg_zhujun','jsrg_liubei','jsrg_wangyun','jsrg_liuyan','jsrg_caocao','jsrg_nanhualaoxian'],
jiangshanrugu_cheng:['jsrg_sunce','jsrg_xuyou','jsrg_lvbu','jsrg_zhanghe','jsrg_zoushi','jsrg_guanyu','jsrg_chendeng','jsrg_zhenji','jsrg_zhangliao','jsrg_xugong','jsrg_chunyuqiong'],
jiangshanrugu_zhuan:['jsrg_guojia','jsrg_zhangfei','jsrg_machao','jsrg_lougui','jsrg_zhangren','jsrg_huangzhong','jsrg_xiahourong','jsrg_sunshangxiang','jsrg_pangtong','jsrg_hansui','jsrg_zhangchu','jsrg_xiahouen','jsrg_fanjiangzhangda'],
+ jiangshanrugu_he:['jsrg_zhugeliang','jsrg_jiangwei','jsrg_luxun','jsrg_zhaoyun','jsrg_simayi','jsrg_guoxun','jsrg_sunlubansunluyu','jsrg_caofang','jsrg_sunjun','jsrg_liuyong','jsrg_weiwenzhugezhi','jsrg_zhangxuan','jsrg_gaoxiang','jsrg_guozhao'],
},
},
character:{
@@ -53,14 +54,34 @@ game.import('character',function(lib,game,ui,get,ai,_status){
jsrg_zhangchu:['female','qun',3,['jsrghuozhong','jsrgrihui']],
jsrg_xiahouen:['male','wei',4,['jsrghujian','jsrgshili'],['die_audio:tw_xiahouen']],
jsrg_fanjiangzhangda:['male','wu',5,['jsrgfushan']],
+ //合
+ jsrg_zhugeliang:['male','shu',3,['jsrgwentian','jsrgchushi','jsrgyinlve']],
+ jsrg_jiangwei:['male','shu',4,['jsrgjinfa','jsrgfumou','jsrgxuanfeng'],['border:wei']],
+ jsrg_luxun:['male','wu',3,['jsrgyoujin','jsrgdailao','jsrgzhubei']],
+ jsrg_zhaoyun:['male','shu',4,['jsrglonglin','jsrgzhendan']],
+ jsrg_simayi:['male','wei',4,['jsrgyingshi','jsrgtuigu']],
+ jsrg_guoxun:['male','wei',4,['jsrgeqian','jsrgfusha']],
+ jsrg_sunlubansunluyu:['female','wu',3,['jsrgdaimou','jsrgfangjie']],
+ jsrg_caofang:['male','wei','3/4',['jsrgzhaotu','jsrgjingju','jsrgweizhui']],
+ jsrg_sunjun:['male','wu',4,['jsrgyaoyan','jsrgbazheng']],
+ jsrg_liuyong:['male','shu',3,['jsrgdanxin','jsrgfengxiang']],
+ jsrg_weiwenzhugezhi:['male','wu',4,['jsrgfuhai']],
+ jsrg_zhangxuan:['female','wu',4,['jsrgtongli','jsrgshezang']],
+ jsrg_gaoxiang:['male','shu',4,['jsrgchiying']],
+ jsrg_guozhao:['female','wei',3,['jsrgpianchong','jsrgzunwei']],
},
characterIntro:{
qiaoxuan:'桥玄(110年-184年6月6日),一作乔玄,字公祖。梁国睢阳县(今河南省商丘市睢阳区)人。东汉时期名臣。桥玄年轻时曾任睢阳县功曹,因坚持追究陈国相羊昌的恶行而闻名。后被举为孝廉,历任洛阳左尉、齐相及上谷、汉阳太守、司徒长史、将作大匠。汉桓帝末年,出任度辽将军,击败鲜卑、南匈奴、高句丽侵扰,保境安民。汉灵帝初年,迁任河南尹、少府、大鸿胪。建宁三年(170年),迁司空。次年,拜司徒。光和元年(178年),升任太尉。桥玄有感于国势日衰,于是称病请辞,改任太中大夫。光和七年(184年),桥玄去世,年七十五。桥玄性格刚强,不阿权贵,待人谦俭,尽管屡历高官,但不因为自己处在高位而有所私请。他为官清廉,去世后连下葬的钱都没有,被时人称为名臣。',
lougui:'娄圭,字子伯,荆州南阳郡(治今河南南阳)人。曹魏时期著名谋士、将军,娄圭年轻时与曹操有交情,曾经随曹操平定冀州,南征刘表,击破马超,立有功劳,连曹操都感叹他的计谋。 后来曹操和他的儿子们一起出去游玩,娄圭当时也一起随行。因言语不当,被南郡(治今湖北荆州)人习授举报,曹操认为有意诽谤,遭杀害。在小说《三国演义》里,娄圭被设定为京兆人(今陕西西安),隐居终南山,道号“梦梅居士”。于第59回登场。',
xiahourong:'夏侯荣(207年—219年) ,字幼权,名将夏侯渊之子。建安二十四年(219年)汉中之战,父亲夏侯渊战死后,夏侯荣不愿逃跑,随后拔剑冲入敌阵,战死。',
+ guoxun:'郭脩(?~253年),一作郭循,字孝先,凉州西平人,三国时期曹魏官员。原为曹魏中郎,被蜀汉将领姜维俘虏后降蜀汉,任左将军,后来刺杀了蜀汉大将军费祎。被曹魏追封为长乐乡侯,谥曰威侯。',
+ caofang:'曹芳(232年-274年),字兰卿,沛国谯县(今安徽省亳州市)人。三国时期曹魏第三位皇帝(239年1月22日-254年10月17日在位),疑为魏武帝曹操曾孙,任城威王曹彰之孙,任城王曹楷之子。太和六年(232年),生于任城王府。青龙三年(235年),选为魏明帝曹叡养子,册封齐王。景初三年(239年),立为皇太子,同日魏明帝曹叡病死,曹芳正式即位,由大将军曹爽和太尉司马懿共同辅政。正始十年,经历高平陵之变,曹爽倒台,政权落入司马氏手中。嘉平六年(254年),中书令李丰和光禄大夫张缉图谋废掉司马师,改立夏侯玄为大将军。司马师平定叛乱后,将曹芳废为齐王,拥戴高贵乡公曹髦继位。西晋建立后,册封邵陵县公。泰始十年(274年),曹芳病逝,终年四十三岁,谥号为厉。',
+ sunjun:'孙峻(219年-256年10月19日),字子远,扬州吴郡富春(今浙江省杭州市)人,昭义中郎将孙静曾孙,定武中郎将孙暠之孙,散骑侍郎孙恭之子。三国时期吴国宗室、权臣。孙峻从小弓马娴熟,胆量非凡。孙权晚年时,孙峻担任武卫都尉,掌握军权,然后又任侍中,开始涉足朝政。孙权临终前,孙峻接受遗诏同诸葛恪、滕胤共同辅佐朝政。此后,其身兼武卫将军,一直主持宫廷的值班、守卫等要害部门,并被封为都乡侯。孙峻生性喜好专断,容不下诸葛恪,于是与吴主孙亮密谋发动政变,在酒宴中设伏兵杀死诸葛恪。孙峻谋杀诸葛恪之后,升任丞相、大将军,督察内外一切军务,假节,晋封富春侯。此后,孙峻独揽朝政。孙峻在任职期间,滥施刑杀,淫乱宫女,和全公主孙鲁班私通。五凤元年(254年),吴侯孙英企图谋杀孙峻,后来事情被泄露,孙英自杀。时隔一年,吴国将军孙仪、张怡、林恂等人乘蜀国使节来访之机,共同谋划诛杀孙峻。后被孙峻发觉,孙仪自杀,林恂等被认为有罪诛死。太平元年(256年),孙峻梦见被诸葛恪所击,因惊悸恐惧发病而死,时年38岁。',
+ sunlubansunluyu:'孙鲁班,孙权之女。孙鲁班与孙权二子孙和不睦。孙权长子孙登死后,孙和被立为太子。孙鲁班向孙权进谗言废孙和太子之位,孙和被废后忧愤而死。
孙鲁育,又名小虎,孙权与步练师之女。吴后期,孙鲁班诬陷孙鲁育参与谋反,于是孙峻杀害了孙鲁育。',
jsrg_caocao:'初平元年二月,董卓徙天子都长安,焚洛阳宫室,众诸侯畏卓兵强,莫敢进。操怒斥众人:“为人臣而临此境,当举义兵以诛暴乱,大众已合,诸君何疑?此一战而天下定矣!”遂引兵汴水,遇卓将徐荣,大破之。操迎天子,攻吕布,伐袁术,安汉室,拜为征西将军。是时,袁绍兼四州之地,将攻许都。操欲扫清寰宇,兴复汉室,遂屯兵官渡。既克绍,操曰:“若天命在吾,吾为周文王矣。”',
jsrg_sunce:'建安五年,操、绍相拒于官渡,孙策欲阴袭许昌,迎汉帝,遂密治兵,部署诸将。未发,会为许贡门客所刺,将计就计,尽托江东于权,诈死以待天时。八月,操、绍决战,孙策亲冒矢石,斩将刈旗,得扬、豫之地。曹操败走冀、青,刘备远遁荆、益。而后历时七年,孙策三分天下已有其二,帝于洛阳,建霸王未竟之功业。权表求吴王,封为仲帝,共治天下。',
- jsrg_guojia:'初平元年二月,郭嘉拜见袁绍,闻曹操怒斥众诸侯,乃对曰:“董卓于汴水或有埋伏,慎之!”曹操未从,果败于徐荣。三月,曹操与郭嘉论天下事:“使孤成大业者,必此人也。”郭嘉从破袁绍,讨谭、尚,连战数克,计定辽东。时年三十八,征乌桓归途郭嘉因劳染疾,命悬之际竟意外饮下柳皮醋水而愈。建安十三年,曹操屯兵赤壁,郭嘉识破连环之计,议上中下三策,可胜刘备。尚未献策,曹操便决意采纳上策,“奉孝之才,足胜孤百倍,卿言上策,如何不取?”由此,赤壁战后曹操尽得天下。'
+ jsrg_guojia:'初平元年二月,郭嘉拜见袁绍,闻曹操怒斥众诸侯,乃对曰:“董卓于汴水或有埋伏,慎之!”曹操未从,果败于徐荣。三月,曹操与郭嘉论天下事:“使孤成大业者,必此人也。”郭嘉从破袁绍,讨谭、尚,连战数克,计定辽东。时年三十八,征乌桓归途郭嘉因劳染疾,命悬之际竟意外饮下柳皮醋水而愈。建安十三年,曹操屯兵赤壁,郭嘉识破连环之计,议上中下三策,可胜刘备。尚未献策,曹操便决意采纳上策,“奉孝之才,足胜孤百倍,卿言上策,如何不取?”由此,赤壁战后曹操尽得天下。',
+ jsrg_zhugeliang:'建兴六年春,汉丞相诸葛亮使赵云、邓芝为先锋,马谡为副将拒箕谷,牵制曹真主力。自率三十万大军攻祁山,三郡叛魏应亮,关中响震。曹叡命张郃拒亮,亮使定军山降将姜维与郃战于街亭,张郃久攻不下。后曹真强攻赵云军,赵云死战,坚守箕谷,马谡、邓芝当场战死忠勇殉国。……既克张郃,曹真溃逃,曹叡弃守长安,迁都邺城。十月,司马懿击退孙权,回援曹真。而后三年,丞相所到之处,无不望风而降,皆箪食壶浆,以迎汉军。尽收豫、徐、兖、并之地,建兴十年春,司马懿父子三人死于诸葛武侯火计,同年,孙权上表称臣,至此四海清平,大汉一统。而后诸葛亮荐蒋琬为丞相,姜维为大将军,自回隆中归隐,后主挽留再三,皆不受。魏延亦辞官相随,侍奉左右。后主时有不决之事,便往隆中拜访相父,均未得面,童子答曰外出云游,遗数锦囊,拆而视之,皆治国之良策也。',
},
characterTitle:{
},
@@ -71,10 +92,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){
allowDuplicate:true,
blankCard:true,
fullimage:true,
+ wuxieable:false,
effect:function(){
'step 0'
- var card=event.cards[0];
- player.chooseUseTarget(card,`蓄谋:是否使用${get.translation(card)}?`,`请选择要使用的目标。若不使用此牌,则判定区内的所有“蓄谋”牌都将被置入弃牌堆。`);
+ var card=get.autoViewAs(event.cards[0]);
+ card.storage.xumou_jsrg=true;
+ player.chooseUseTarget(card,event.cards,`蓄谋:是否使用${get.translation(card)}?`,`请选择要使用的目标。若不使用此牌,则判定区内的所有“蓄谋”牌都将被置入弃牌堆。`);
'step 1'
if(!result.bool){
var cards=player.getCards('j',card=>{
@@ -82,6 +105,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){
});
if(cards.length>0) player.loseToDiscardpile(cards);
}
+ else{
+ player.addTempSkill('xumou_jsrg_temp','phaseChange');
+ player.markAuto('xumou_jsrg_temp',[event.cards[0].name])
+ }
},
},
ying:{
@@ -113,6 +140,1857 @@ game.import('character',function(lib,game,ui,get,ai,_status){
},
},
skill:{
+ //江山如故·合
+ //蓄谋临时禁用
+ xumou_jsrg_temp:{
+ charlotte:true,
+ onremove:true,
+ mod:{
+ cardEnabled(card,player){
+ if(!card.storage||!card.storage.xumou_jsrg) return;
+ if(player.getStorage('xumou_jsrg_temp').includes(get.name(card,false))) return false;
+ },
+ },
+ },
+ //404诸葛亮
+ jsrgwentian:{
+ audio:2,
+ trigger:{
+ player:['phaseZhunbeiBegin','phaseJudgeBegin','phaseDrawBegin','phaseUseBegin','phaseDiscardBegin','phaseJieshuBegin'],
+ },
+ usable:1,
+ prompt2:'观看牌堆顶的五张牌,将其中一张交给其他角色,并将其余牌置于牌堆顶或牌堆底',
+ group:'jsrgwentian_viewas',
+ async content(event,trigger,player){
+ const cards=get.cards(5);
+ game.cardsGotoOrdering(cards);
+ const {result}=await player.chooseButton([
+ '问天:将一张牌交给一名其他角色',
+ cards
+ ],true);
+ if(result.bool){
+ const {result:result2}=await player.chooseTarget(`将${get.translation(result.links)}交给一名其他角色`,lib.filter.notMe,true).set('ai',target=>{
+ return get.attitude(get.player(),target);
+ });
+ if(result2.bool){
+ cards.removeArray(result.links);
+ const target=result2.targets[0];
+ player.line(target,'green');
+ await target.gain(result.links,'gain2').set('giver',player);
+ }
+ }
+ const next=player.chooseToMove();
+ next.set('list',[
+ ['牌堆顶',cards.filterInD()],
+ ['牌堆底'],
+ ]);
+ next.set('prompt','问天:点击将牌移动到牌堆顶或牌堆底');
+ next.processAI=list=>{
+ const cards=list[0][1],player=_status.event.player;
+ const top=[];
+ const judges=player.getCards('j');
+ let stopped=false;
+ if(!player.hasWuxie()){
+ for(let i=0;ijudge(b)-judge(a));
+ if(judge(cards[0])<0){
+ stopped=true;break;
+ }
+ else{
+ top.unshift(cards.shift());
+ }
+ }
+ }
+ let bottom;
+ if(!stopped){
+ cards.sort((a,b)=>get.value(b,player)-get.value(a,player));
+ while(cards.length){
+ if(get.value(cards[0],player)<=5) break;
+ top.unshift(cards.shift());
+ }
+ }
+ bottom=cards;
+ return [top,bottom];
+ }
+ const {result:{moved}}=await next;
+ const top=moved[0];
+ const bottom=moved[1];
+ top.reverse();
+ game.cardsGotoPile(
+ top.concat(bottom),
+ ['top_cards',top],
+ (event,card)=>{
+ if(event.top_cards.includes(card)) return ui.cardPile.firstChild;
+ return null;
+ }
+ );
+ player.popup(get.cnNumber(top.length)+'上'+get.cnNumber(bottom.length)+'下');
+ game.log(player,'将'+get.cnNumber(top.length)+'张牌置于牌堆顶');
+ game.asyncDelayx();
+ },
+ subSkill:{
+ viewas:{
+ audio:'jsrgwentian',
+ enable:'chooseToUse',
+ filter:function(event,player){
+ for(const name of ['wuxie','huogong']){
+ if(event.filterCard({name},player,event)) return true;
+ }
+ return false;
+ },
+ hiddenCard:function(player,name){
+ if(player.isTempBanned('jsrgwentian')) return false;
+ return name=='wuxie';
+ },
+ viewAs:function(cards,player){
+ const event=get.event(),filter=event._backup.filterCard;
+ for(const name of ['wuxie','huogong']){
+ if(filter({name},player,event)) return {name};
+ }
+ return null;
+ },
+ filterCard:()=>false,
+ selectCard:-1,
+ prompt:function(){
+ const player=get.player();
+ const event=get.event(),filter=event._backup.filterCard;
+ let str='将牌堆顶的牌当【';
+ for(const name of ['wuxie','huogong']){
+ if(filter({name},player,event)){
+ str+=get.translation(name); break;
+ }
+ }
+ str+='】使用';
+ return str;
+ },
+ precontent(){
+ player.logSkill('jsrgwentian');
+ const cards=get.cards();
+ event.result.cards=cards;
+ delete event.result.skill;
+ game.cardsGotoOrdering(cards);
+ const color=event.result.card.name=='wuxie'?'black':'red';
+ if(get.color(cards,false)!=color){
+ player.tempBanSkill('jsrgwentian','roundStart');
+ }
+ }
+ }
+ }
+ },
+ jsrgchushi:{
+ audio:2,
+ enable:'phaseUse',
+ usable:1,
+ filter(event,player){
+ const zhu=get.zhu(player);
+ if(!zhu||!zhu.isZhu2()) return false;
+ return !player.isZhu2();
+ },
+ async content(event,trigger,player){
+ player.chooseToDebate(game.filterPlayer(current=>{
+ return current==player||current.isZhu2();
+ })).set('callback',async event=>{
+ const result=event.debateResult;
+ if(result.bool&&result.opinion){
+ const {opinion,targets}=result;
+ targets.sortBySeat();
+ if(opinion=='red'){
+ do{
+ for(const current of targets){
+ await current.draw();
+ }
+ }
+ while(targets.map(current=>{
+ return current.countCards('h');
+ }).reduce((p,c)=>{
+ return p+c;
+ },0)<7);
+ }
+ else{
+ player.addMark('jsrgchushi_add',1,false);
+ player.addTempSkill('jsrgchushi_add','roundStart');
+ }
+ }
+ })
+ },
+ subSkill:{
+ add:{
+ audio:'jsrgchushi',
+ trigger:{source:'damageBegin1'},
+ filter:function(event){
+ return event.hasNature('linked');
+ },
+ forced:true,
+ charlotte:true,
+ onremove:true,
+ async content(_,trigger,player){
+ trigger.num+=player.countMark('jsrgchushi_add');
+ },
+ ai:{
+ damageBonus:true,
+ skillTagFilter:function(player,tag,arg){
+ if(tag==='damageBonus') return arg&&arg.card&&game.hasNature(arg.card,'linked');
+ }
+ },
+ intro:{
+ content:'造成的属性伤害+#',
+ }
+ }
+ }
+ },
+ jsrgyinlve:{
+ audio:2,
+ trigger:{
+ global:'damageBegin4',
+ },
+ filter:function(event,player){
+ return event.player.isIn()&&['fire','thunder'].some(n=>!player.hasSkill(`jsrgyinlve_${n}`)&&event.hasNature(n));
+ },
+ check:function(event,player){
+ if(get.damageEffect(event.player,event.source,player,get.natureList(event.nature))<-5) return true;
+ return false;
+ },
+ logTarget:'player',
+ async content(event,trigger,player){
+ trigger.cancel();
+ const natures=['fire','thunder'];
+ let index;
+ if(natures.every(n=>!player.hasSkill(`jsrgyinlve_${n}`)&&trigger.hasNature(n))){
+ const {result}=await player.chooseControl(['摸牌阶段','弃牌阶段']).set('prompt','请选择要新回合内仅有的阶段');
+ index=result.index;
+ }
+ else index=[0,1].find(i=>!player.hasSkill(`jsrgyinlve_${natures[i]}`)&&trigger.hasNature(natures[i]));
+ player.addTempSkill(`jsrgyinlve_${natures[index]}`,'roundStart');
+ player.insertPhase().set('phaseList',[['phaseDraw','phaseDiscard'][index]]);
+ },
+ subSkill:{
+ fire:{charlotte:true},
+ thunder:{charlotte:true},
+ }
+ },
+ //姜维
+ jsrgjinfa:{
+ audio:2,
+ enable:'phaseUse',
+ usable:1,
+ filterCard:true,
+ position:'h',
+ discard:false,
+ lose:false,
+ delay:false,
+ check:function(){
+ return 1+Math.random();
+ },
+ async content(event,trigger,player){
+ await player.showCards(event.cards);
+ player.chooseToDebate(game.filterPlayer(current=>{
+ return current.maxHp<=player.maxHp;
+ })).set('callback',async (event)=>{
+ const result=event.debateResult;
+ if(result.bool&&result.opinion){
+ const {cards:fixedCards}=event.getParent('jsrgjinfa');
+ const color=get.color(fixedCards);
+ const {opinion,targets}=result;
+ if(opinion==color){
+ const {result}=await player.chooseTarget('是否令至多两名参与议事的角色将手牌摸至体力上限?',[1,2],(card,player,target)=>{
+ return get.event('targets').includes(target);
+ }).set('targets',targets).set('ai',target=>{
+ const player=get.player();
+ const att=get.attitude(player,target);
+ if(att<=0) return -1;
+ return att*Math.sqrt(Math.max(0.1,target.maxHp-target.countCards('h')));
+ });
+ if(result.bool){
+ const targets=result.targets;
+ targets.sortBySeat();
+ player.line(targets,'green');
+ for(const current of targets){
+ if(current.countCards('h'){
+ if(!get.event('change')) return 'cancel2';
+ const controls=get.event('controls');
+ const groups=['wei','shu'].filter(g=>controls.includes(g));
+ if(groups.length) return groups.randomGet();
+ return controls.randomGet();
+ }).set('change',['wei','shu'].includes(player.group)?(Math.random()<0.5):true);
+ if(control!='cancel2'){
+ player.popup(control+'2',get.groupnature(control,'raw'));
+ player.changeGroup(control);
+ }
+ }
+ });
+ },
+ ai:{
+ order:function(item,player){
+ if(player.countCards('h')==1) return 10;
+ return 1;
+ },
+ result:{
+ player:1,
+ },
+ }
+ },
+ jsrgfumou:{
+ audio:2,
+ trigger:{global:'chooseToDebateAfter'},
+ groupSkill:true,
+ forced:true,
+ locked:false,
+ filter:function(event,player){
+ if(player.group!='wei') return false;
+ if(!event.targets.includes(player)) return false;
+ if(event.red.some(i=>i[0]==player)) return event.black.length;
+ if(event.black.some(i=>i[0]==player)) return event.red.length;
+ return false;
+ },
+ async content(event,trigger,player){
+ const targets=[];
+ if(trigger.red.some(i=>i[0]==player)) targets.addArray(trigger.black.map(i=>i[0]));
+ if(trigger.black.some(i=>i[0]==player)) targets.addArray(trigger.red.map(i=>i[0]));
+ player.line(targets,'thunder');
+ targets.forEach(target=>{
+ target.addTempSkill('jsrgfumou_forbid');
+ target.markAuto('jsrgfumou_forbid',['red','black'].filter(color=>{
+ return trigger[color].some(i=>i[0]==target);
+ }))
+ });
+ game.broadcastAll(targets=>{
+ lib.skill.jsrgfumou_backup.targets=targets;
+ },targets);
+ const next=player.chooseToUse();
+ next.set('openskilldialog',`是否将一张【影】当【出其不意】对一名与你意见不同的角色使用?`);
+ next.set('norestore',true);
+ next.set('_backupevent','jsrgfumou_backup');
+ next.set('custom',{
+ add:{},
+ replace:{window:function(){}}
+ });
+ next.backup('jsrgfumou_backup');
+ },
+ subSkill:{
+ backup:{
+ filterCard:function(card){
+ return get.itemtype(card)=='card'&&get.name(card)=='ying';
+ },
+ viewAs:{
+ name:'chuqibuyi',
+ },
+ selectCard:1,
+ position:'hs',
+ log:false,
+ filterTarget:function(card,player,target){
+ const targets=lib.skill.jsrgfumou_backup.targets;
+ if(!targets.includes(target)||ui.selected.targets.containsSome(targets)) return false;
+ return lib.filter.targetEnabled.apply(this,arguments);
+ },
+ ai1:function(card){
+ return 6-get.value(card);
+ },
+ precontent:function(){
+ delete event.result.skill;
+ },
+ },
+ forbid:{
+ charlotte:true,
+ onremove:true,
+ mod:{
+ cardEnabled:function(card,player){
+ if(player.getStorage('jsrgfumou_forbid').includes(get.color(card))) return false;
+ },
+ cardRespondable:function(card,player){
+ if(player.getStorage('jsrgfumou_forbid').includes(get.color(card))) return false;
+ },
+ cardSavable:function(card,player){
+ if(player.getStorage('jsrgfumou_forbid').includes(get.color(card))) return false;
+ },
+ },
+ mark:true,
+ intro:{
+ content:'本回合不能使用或打出$牌',
+ },
+ }
+ }
+ },
+ jsrgxuanfeng:{
+ audio:2,
+ enable:'chooseToUse',
+ filterCard:{name:'ying'},
+ position:'hs',
+ groupSkill:true,
+ locked:false,
+ viewAs:{
+ name:'sha',
+ nature:'stab',
+ storage:{jsrgxuanfeng:true},
+ },
+ viewAsFilter(player){
+ if(player.group!='shu') return false;
+ if(!player.countCards('hs','ying')) return false;
+ },
+ prompt:'将一张【影】当无距离和次数限制的刺【杀】使用',
+ check(card){
+ const val=get.value(card);
+ return 5-val;
+ },
+ mod:{
+ targetInRange:function(card,player,target){
+ if(card.storage&&card.storage.jsrgxuanfeng) return true;
+ },
+ cardUsable:function(card){
+ if(card.storage&&card.storage.jsrgxuanfeng) return Infinity;
+ }
+ },
+ ai:{
+ order:2,
+ }
+ },
+ //陆逊
+ jsrgyoujin:{
+ audio:2,
+ trigger:{player:'phaseUseBegin'},
+ filter(event,player){
+ return game.hasPlayer(current=>{
+ return player.canCompare(current);
+ });
+ },
+ direct:true,
+ async content(event,trigger,player){
+ const {result}=await player.chooseTarget(get.prompt2('jsrgyoujin'),(card,player,target)=>{
+ return player.canCompare(target);
+ }).set('ai',target=>{
+ if(!get.event('goon')) return 0;
+ return -get.attitude(get.player(),target);
+ }).set('goon',player.countCards('hs',['shan','caochuan'])||player.getHp()>=3);
+ if(!result.bool) return;
+ const {targets}=result,target=targets[0];
+ player.logSkill('jsrgyoujin',target);
+ const {result:result2}=await player.chooseToCompare(target).set('small',true);
+ player.addTempSkill('jsrgyoujin_forbid');
+ player.markAuto('jsrgyoujin_forbid',[result2.num1]);
+ target.addTempSkill('jsrgyoujin_forbid');
+ target.markAuto('jsrgyoujin_forbid',[result2.num2]);
+ if(!result2.tie){
+ const targets=[target,player];
+ if(result2.bool) targets.reverse();
+ const sha=new lib.element.VCard({name:'sha'});
+ if(targets[0].canUse(sha,targets[1],false)){
+ targets[0].useCard(sha,targets[1],false);
+ }
+ }
+ },
+ subSkill:{
+ forbid:{
+ charlotte:true,
+ onremove:true,
+ mod:{
+ cardEnabled2:function(card,player){
+ if(get.itemtype(card)=='card'&&player.getStorage('jsrgyoujin_forbid').some(num=>num>get.number(card))) return false;
+ },
+ },
+ mark:true,
+ intro:{
+ content:'本回合不能使用或打出点数小于$的手牌',
+ },
+ }
+ }
+ },
+ jsrgdailao:{
+ audio:2,
+ enable:'phaseUse',
+ filter(event,player){
+ return !player.hasCard(card=>{
+ return player.hasUseTarget(card);
+ });
+ },
+ async content(event,trigger,player){
+ await player.showHandcards();
+ await player.draw(2);
+ const evt=event.getParent('phase');
+ if(evt){
+ game.resetSkills();
+ _status.event=evt;
+ _status.event.finish();
+ _status.event.untrigger(true);
+ }
+ },
+ ai:{
+ order:0.0001,
+ result:{player:1},
+ }
+ },
+ jsrgzhubei:{
+ audio:2,
+ trigger:{source:'damageBegin1'},
+ forced:true,
+ init(player){
+ player.addSkill('jsrgzhubei_record');
+ },
+ filter(event,player){
+ return event.player.hasHistory('damage',evt=>{
+ return evt.source==player;
+ });
+ },
+ logTarget:'player',
+ async content(event,trigger,player){
+ trigger.num++;
+ },
+ subSkill:{
+ record:{
+ trigger:{
+ global:['loseAfter','equipAfter','addJudgeAfter','gainAfter','loseAsyncAfter','addToExpansionAfter'],
+ },
+ charlotte:true,
+ silent:true,
+ filter(event,player){
+ return game.hasPlayer(current=>{
+ if(current.countCards('h')) return false;
+ const evt=event.getl(current);
+ return evt&&evt.hs&&evt.hs.length;
+ });
+ },
+ async content(event,trigger,player){
+ game.countPlayer(current=>{
+ if(current.countCards('h')) return false;
+ const evt=trigger.getl(current);
+ if(evt&&evt.hs&&evt.hs.length) current.addTempSkill('jsrgzhubei_lost');
+ });
+ },
+ },
+ lost:{charlotte:true},
+ },
+ mod:{
+ cardUsableTarget(card,player,target){
+ if(target.hasSkill('jsrgzhubei_lost')) return true;
+ },
+ },
+ },
+ //赵云
+ jsrglonglin:{
+ audio:2,
+ trigger:{
+ global:'useCardToPlayered',
+ },
+ usable:1,
+ filter(event,player){
+ if(event.player==player) return false;
+ if(event.card.name!='sha') return false;
+ return event.isFirstTarget&&event.player.isPhaseUsing();
+ },
+ direct:true,
+ async content(event,trigger,player){
+ const juedou=new lib.element.VCard({name:'juedou',storage:{jsrglonglin:true}});
+ const {result}=await player.chooseToDiscard(get.prompt2('jsrglonglin'),'he').set('ai',card=>{
+ if(get.event('goon')) return 5-get.value(card);
+ return 0;
+ }).set('goon',(trigger.player.canUse(juedou,player)?Math.max(0,get.effect(player,juedou,trigger.player,trigger.player)):0)+trigger.targets.map(target=>{
+ return get.effect(target,trigger.card,trigger.player,player);
+ }).reduce((p,c)=>{
+ return p+c;
+ },0)<-4).set('logSkill',['jsrglonglin',trigger.player]);
+ if(result.bool){
+ trigger.excluded.addArray(trigger.targets);
+ game.asyncDelayx();
+ if(trigger.player.canUse(juedou,player)){
+ const {result}=await trigger.player.chooseBool(`是否视为对${get.translation(player)}使用一张【决斗】?`).set('choice',get.effect(player,juedou,trigger.player,trigger.player)>=0);
+ if(result.bool){
+ player.addTempSkill('jsrglonglin_source');
+ trigger.player.useCard(juedou,player);
+ }
+ }
+ }
+ },
+ subSkill:{
+ source:{
+ trigger:{source:'damageSource'},
+ charlotte:true,
+ forced:true,
+ popup:false,
+ filter(event,player){
+ return event.card&&event.card.storage&&event.card.storage.jsrglonglin;
+ },
+ async content(event,trigger,player){
+ player.line(trigger.player);
+ trigger.player.addTempSkill('jsrglonglin_forbid');
+ }
+ },
+ forbid:{
+ mod:{
+ cardEnabled:function(card,player){
+ if(!card.cards) return;
+ if(card.cards.some(cardx=>get.position(cardx)=='h')) return false;
+ },
+ cardSavable:function(card,player){
+ if(!card.cards) return;
+ if(card.cards.some(cardx=>get.position(cardx)=='h')) return false;
+ },
+ },
+ charlotte:true,
+ mark:true,
+ intro:{
+ content:'不能使用手牌',
+ },
+ },
+ },
+ },
+ jsrgzhendan:{
+ audio:2,
+ trigger:{
+ player:'damageEnd',
+ global:'roundStart',
+ },
+ filter(event,player){
+ let count=0;
+ let roundCount=1+(event.name!='damage');
+ const curLen=player.actionHistory.length;
+ for(let i=curLen-1;i>=0;i--){
+ if(roundCount==1&&game.hasPlayer(current=>{
+ const history=current.actionHistory[i];
+ if(!history.isMe||history.isSkipped) return false;
+ return true;
+ })){
+ count++;
+ }
+ if(player.actionHistory[i].isRound) roundCount--;
+ if(roundCount<=0) break;
+ }
+ if(!player.storage.jsrgzhendan_mark&&count>0) return true;
+ return false;
+ },
+ forced:true,
+ locked:false,
+ group:'jsrgzhendan_viewas',
+ async content(event,trigger,player){
+ let count=0;
+ let roundCount=1+(trigger.name!='damage');
+ const curLen=player.actionHistory.length;
+ for(let i=curLen-1;i>=0;i--){
+ if(roundCount==1&&game.hasPlayer(current=>{
+ const history=current.actionHistory[i];
+ if(!history.isMe||history.isSkipped) return false;
+ return true;
+ })){
+ count++;
+ }
+ if(player.actionHistory[i].isRound) roundCount--;
+ if(roundCount<=0) break;
+ }
+ count=Math.min(5,count);
+ await player.draw(count);
+ if(trigger.name=='damage'){
+ player.tempBanSkill('jsrgzhendan','roundStart');
+ player.storage.jsrgzhendan_mark=true;
+ player.when({global:'roundStart'}).assign({
+ lastDo:true,
+ }).then(()=>{
+ delete player.storage.jsrgzhendan_mark;
+ });
+ }
+ },
+ subSkill:{
+ viewas:{
+ audio:'jsrgzhendan',
+ enable:['chooseToUse','chooseToRespond'],
+ filter(event,player){
+ if(event.type=='wuxie') return false;
+ if(!_status.connectMode&&!player.countCards('hs',card=>{
+ return get.type2(card)!='basic';
+ })) return false;
+ return get.inpileVCardList(info=>{
+ if(info[0]!='basic') return false;
+ return event.filterCard({name:info[2],nature:info[3]},player,event);
+ }).length;
+ },
+ chooseButton:{
+ dialog(event,player){
+ const vcards=get.inpileVCardList(info=>{
+ if(info[0]!='basic') return false;
+ return event.filterCard({name:info[2],nature:info[3]},player,event);
+ });
+ return ui.create.dialog('镇胆',[vcards,'vcard']);
+ },
+ check(button){
+ if(get.event().getParent().type!='phase') return 1;
+ return get.player().getUseValue({name:button.link[2],nature:button.link[3]});
+ },
+ backup(links,player){
+ return {
+ audio:'jsrgzhendan',
+ popname:true,
+ viewAs:{name:links[0][2],nature:links[0][3]},
+ filterCard(card,player){
+ return get.type2(card)!='basic';
+ },
+ selectCard:1,
+ position:'hs',
+ }
+ },
+ prompt(links,player){
+ return '将一张非基本手牌当'+(get.translation(links[0][3])||'')+get.translation(links[0][2])+'使用或打出';
+ }
+ },
+ hiddenCard(player,name){
+ return get.type(name)=='basic'&&player.countCards('hs')>0;
+ },
+ ai:{
+ respondSha:true,
+ respondShan:true,
+ skillTagFilter(player){
+ return player.countCards('hs')>0;
+ },
+ order:0.5,
+ result:{
+ player(player){
+ if(get.event().dying){
+ return get.attitude(player,get.event().dying);
+ }
+ return 1;
+ },
+ },
+ },
+ },
+ viewas_backup:{},
+ }
+ },
+ //司马懿
+ jsrgyingshi:{
+ audio:2,
+ trigger:{player:'turnOverAfter'},
+ async content(event,trigger,player){
+ const number=(game.dead.length>2)?5:3;
+ const cards=get.bottomCards(number);
+ game.cardsGotoOrdering(cards);
+ const next=player.chooseToMove();
+ next.set('list',[
+ ['牌堆顶'],
+ ['牌堆底',cards.reverse()],
+ ]);
+ next.set('prompt','鹰眎:点击将牌移动到牌堆顶或牌堆底');
+ next.processAI=list=>{
+ const cards=list[1][1],player=_status.event.player;
+ const top=[];
+ const judges=player.getCards('j');
+ let stopped=false;
+ if(!player.hasWuxie()){
+ for(let i=0;ijudge(b)-judge(a));
+ if(judge(cards[0])<0){
+ stopped=true;break;
+ }
+ else{
+ top.unshift(cards.shift());
+ }
+ }
+ }
+ let bottom;
+ if(!stopped){
+ cards.sort((a,b)=>get.value(b,player)-get.value(a,player));
+ while(cards.length){
+ if(get.value(cards[0],player)<=5) break;
+ top.unshift(cards.shift());
+ }
+ }
+ bottom=cards;
+ return [top,bottom];
+ }
+ const {result:{moved}}=await next;
+ const top=moved[0];
+ const bottom=moved[1];
+ top.reverse();
+ game.cardsGotoPile(
+ top.concat(bottom),
+ ['top_cards',top],
+ (event,card)=>{
+ if(event.top_cards.includes(card)) return ui.cardPile.firstChild;
+ return null;
+ }
+ );
+ player.popup(get.cnNumber(top.length)+'上'+get.cnNumber(bottom.length)+'下');
+ game.log(player,'将'+get.cnNumber(top.length)+'张牌置于牌堆顶');
+ game.asyncDelayx();
+ },
+ },
+ jsrgtuigu:{
+ audio:2,
+ trigger:{player:'phaseBegin'},
+ prompt2(event,player){
+ const num=Math.floor(game.countPlayer()/2);
+ return `你翻面,令你本回合的手牌上限+${num},摸${get.cnNumber(num)}张牌,视为使用一张【解甲归田】(目标角色不能使用这些牌直到其下回合结束)。`;
+ },
+ group:['jsrgtuigu_insert','jsrgtuigu_recover'],
+ async content(event,trigger,player){
+ await player.turnOver();
+ const num=Math.floor(game.countPlayer()/2);
+ player.addTempSkill('jsrgtuigu_handcard');
+ player.addMark('jsrgtuigu_handcard',num,false);
+ await player.draw(num);
+ const jiejia=new lib.element.VCard({name:'jiejia',storage:{jsrgtuigu:true}});
+ if(player.hasUseTarget(jiejia)){
+ player.addTempSkill('jsrgtuigu_block');
+ player.chooseUseTarget(jiejia,true);
+ }
+ },
+ subSkill:{
+ insert:{
+ audio:'jsrgtuigu',
+ trigger:{global:'roundStart'},
+ filter(event,player){
+ const curLen=player.actionHistory.length;
+ if(curLen<=2) return false;
+ for(let i=curLen-2;i>=0;i--){
+ const history=player.actionHistory[i];
+ if(history.isMe&&!history.isSkipped) return false;
+ if(history.isRound) break;
+ }
+ return true;
+ },
+ forced:true,
+ locked:false,
+ async content(event,trigger,player){
+ const evt=trigger;
+ player.insertPhase();
+ if(evt.player!=player&&!evt._finished){
+ evt.finish();
+ evt._triggered=5;
+ evt.player.insertPhase();
+ }
+ },
+ },
+ recover:{
+ audio:'jsrgtuigu',
+ trigger:{
+ player:'loseAfter',
+ global:['gainAfter','equipAfter','addJudgeAfter','loseAsyncAfter','addToExpansionAfter'],
+ },
+ filter(event,player){
+ if(player.isHealthy()) return false;
+ const evt=event.getl(player);
+ return evt&&evt.es&&evt.es.length>0;
+ },
+ forced:true,
+ locked:false,
+ async content(event,trigger,player){
+ player.recover();
+ }
+ },
+ handcard:{
+ markimage:'image/card/handcard.png',
+ intro:{
+ content(storage,player){
+ return '手牌上限+'+storage;
+ }
+ },
+ charlotte:true,
+ mod:{
+ maxHandcard(player,num){
+ return num+player.countMark('jsrgtuigu_handcard');
+ }
+ },
+ },
+ block:{
+ trigger:{global:'gainAfter'},
+ filter(event,player){
+ if(event.getParent().name!='jiejia') return false;
+ const card=event.getParent(2).card;
+ if(card&&card.storage&&card.storage.jsrgtuigu) return true;
+ return false;
+ },
+ charlotte:true,
+ forced:true,
+ silent:true,
+ content(){
+ trigger.player.addGaintag(trigger.cards,'jsrgtuigu');
+ trigger.player.addTempSkill('jsrgtuigu_blocked',{player:'phaseAfter'});
+ }
+ },
+ blocked:{
+ mod:{
+ cardEnabled2(card){
+ if(get.itemtype(card)=='card'&&card.hasGaintag('jsrgtuigu')) return false;
+ },
+ },
+ charlotte:true,
+ forced:true,
+ popup:false,
+ onremove(player){
+ player.removeGaintag('jsrgtuigu');
+ },
+ },
+ }
+ },
+ //郭循
+ jsrgeqian:{
+ audio:2,
+ trigger:{player:'useCardToPlayered'},
+ filter(event,player){
+ if(!event.isFirstTarget||event.targets.length!=1||event.target==player) return false;
+ if(event.card.name=='sha') return true;
+ return event.getParent(3).name=='xumou_jsrg';
+ },
+ prompt2(event,player){
+ return `令${get.translation(event.card)}不计入次数限制,且你获得${get.translation(event.target)}一张牌,然后其可以令你本回合至其的距离+2`;
+ },
+ group:'jsrgeqian_prepare',
+ async content(event,trigger,player){
+ if(trigger.addCount!==false){
+ trigger.addCount=false;
+ var stat=player.getStat().card,name=trigger.card.name;
+ if(typeof stat[name]=='number') stat[name]--;
+ }
+ await player.gainPlayerCard(trigger.target,'he',true);
+ const {result:{bool}}=await trigger.target.chooseBool(`是否令${get.translation(player)}至你的距离于本回合内+2?`).set('ai',()=>true);
+ if(bool){
+ player.addTempSkill('jsrgeqian_distance');
+ if(!player.storage.jsrgeqian_distance) player.storage.jsrgeqian_distance={};
+ const id=trigger.target.playerid;
+ if(typeof player.storage.jsrgeqian_distance[id]!='number') player.storage.jsrgeqian_distance[id]=0;
+ player.storage.jsrgeqian_distance[id]+=2;
+ player.markSkill('jsrgeqian_distance');
+ }
+ },
+ subSkill:{
+ prepare:{
+ audio:'jsrgeqian',
+ trigger:{player:'phaseJieshuBegin'},
+ filter(event,player){
+ return player.countCards('h');
+ },
+ direct:true,
+ async content(event,trigger,player){
+ while(true){
+ const {result:{bool,cards}}=await player.chooseCard(get.prompt('jsrgeqian'),'你可以蓄谋任意次').set('ai',card=>{
+ const player=get.player();
+ if(player.hasValueTarget(card)) return player.getUseValue(card);
+ return 0;
+ });
+ if(!bool) break;
+ player.addJudge({name:'xumou_jsrg'},cards);
+ }
+ },
+ },
+ distance:{
+ onremove:true,
+ charlotte:true,
+ mod:{
+ globalFrom(player,target,distance){
+ if(!player.storage.jsrgeqian_distance) return;
+ const dis=player.storage.jsrgeqian_distance[target.playerid];
+ if(typeof dis=='number') return distance+dis;
+ },
+ },
+ intro:{
+ content(storage,player){
+ if(!storage) return;
+ const map=(_status.connectMode?lib.playerOL:game.playerMap);
+ let str=`你本回合:`;
+ for(const id in storage){
+ str+='至'+get.translation(map[id])+'的距离+'+storage[id];
+ }
+ return str;
+ }
+ }
+ },
+ }
+ },
+ jsrgfusha:{
+ audio:2,
+ enable:'phaseUse',
+ limited:true,
+ skillAnimation:true,
+ animationColor:'fire',
+ filter(event,player){
+ return game.countPlayer(current=>{
+ return player.inRange(current);
+ })==1;
+ },
+ filterTarget(card,player,target){
+ return player.inRange(target);
+ },
+ selectTarget:-1,
+ async content(event,trigger,player){
+ player.awakenSkill('jsrgfusha');
+ event.target.damage(Math.min(game.countPlayer(),player.getAttackRange()));
+ },
+ ai:{
+ order:1,
+ result:{
+ target:-2,
+ },
+ },
+ },
+ //大小虎
+ jsrgdaimou:{
+ audio:2,
+ trigger:{
+ global:'useCardToPlayer',
+ },
+ filter(event,player){
+ if(event.card.name!='sha') return false;
+ if(event.target!=player) return !player.hasSkill('jsrgdaimou_other');
+ return !player.hasSkill('jsrgdaimou_me')&&player.hasCard(card=>{
+ return (card.viewAs||card.name)=='xumou_jsrg'&&lib.filter.cardDiscardable(card,player,'jsrgdaimou');
+ },'j');
+ },
+ direct:true,
+ async content(event,trigger,player){
+ if(trigger.target==player){
+ player.logSkill('jsrgdaimou');
+ player.addTempSkill('jsrgdaimou_me');
+ const {result:{bool,links}}=await player.chooseButton([
+ '殆谋:请弃置区域里的一张蓄谋牌',
+ player.getCards('j',card=>{
+ return (card.viewAs||card.name)=='xumou_jsrg';
+ })
+ ],true).set('filterButton',button=>{
+ return lib.filter.cardDiscardable(button.link,get.player(),'jsrgdaimou');
+ }).set('ai',button=>{
+ const player=get.player();
+ return 1/Math.max(0.01,player.getUseValue(button.link));
+ });
+ if(bool){
+ player.discard(links);
+ }
+ }
+ else{
+ const {result:{bool}}=await player.chooseBool(get.prompt('jsrgdaimou'),'你可以用牌堆顶的牌蓄谋').set('ai',()=>true);
+ if(bool){
+ player.logSkill('jsrgdaimou');
+ player.addTempSkill('jsrgdaimou_other');
+ player.addJudge({name:'xumou_jsrg'},get.cards());
+ }
+ }
+ },
+ subSkill:{
+ me:{charlotte:true},
+ other:{charlotte:true},
+ },
+ },
+ jsrgfangjie:{
+ audio:2,
+ trigger:{player:'phaseZhunbeiBegin'},
+ direct:true,
+ async content(event,trigger,player){
+ if(!player.hasCard(card=>{
+ return (card.viewAs||card.name)=='xumou_jsrg';
+ },'j')){
+ player.logSkill('jsrgfangjie');
+ await player.recover();
+ await player.draw();
+ }
+ else{
+ const {result:{bool,links}}=await player.chooseButton([
+ '是否弃置区域里的任意张蓄谋牌并失去〖芳洁〗?',
+ player.getCards('j',card=>{
+ return (card.viewAs||card.name)=='xumou_jsrg';
+ })
+ ],[1,Infinity]).set('filterButton',button=>{
+ return lib.filter.cardDiscardable(button.link,get.player(),'jsrgdaimou');
+ }).set('ai',()=>0);
+ if(bool){
+ player.logSkill('jsrgfangjie');
+ await player.discard(links);
+ player.removeSkillLog('jsrgfangjie');
+ }
+ }
+ },
+ },
+ //曹芳
+ jsrgzhaotu:{
+ audio:2,
+ enable:'chooseToUse',
+ viewAs:{name:'lebu'},
+ position:'hes',
+ viewAsFilter(player){
+ return player.countCards('hes');
+ },
+ filterCard(card,player){
+ return get.color(card)=='red'&&get.type2(card)!='trick';
+ },
+ onuse(result,player){
+ player.tempBanSkill('jsrgzhaotu',null,false);
+ result.targets[0].insertPhase();
+ result.targets[0].addTempSkill('jsrgzhaotu_handcard',{player:'phaseAfter'});
+ result.targets[0].addMark('jsrgzhaotu_handcard',2,false);
+ },
+ subSkill:{
+ handcard:{
+ intro:{
+ content(storage,player){
+ return '手牌上限-'+storage;
+ }
+ },
+ charlotte:true,
+ mod:{
+ maxHandcard(player,num){
+ return num-player.countMark('jsrgzhaotu_handcard');
+ }
+ },
+ },
+ },
+ ai:{
+ order:5,
+ result:{
+ target(player,target){
+ if(player.hasSkill('jsrgjingju')||player.hasZhuSkill('jsrgweizhui')) return get.attitude(player,target);
+ return -1;
+ },
+ },
+ },
+ },
+ jsrgjingju:{
+ audio:2,
+ enable:'chooseToUse',
+ filter(event,player){
+ if(event.type=='wuxie'||event.jsrgjingju) return false;
+ if(!player.canMoveCard(null,false,game.filterPlayer(i=>i!=player),player,card=>{
+ return get.position(card)=='j';
+ })) return false;
+ return get.inpileVCardList(info=>{
+ if(info[0]!='basic') return false;
+ return event.filterCard({name:info[2],nature:info[3]},player,event);
+ }).length;
+ },
+ chooseButton:{
+ dialog:function(event,player){
+ const vcards=get.inpileVCardList(info=>{
+ if(info[0]!='basic') return false;
+ return event.filterCard({name:info[2],nature:info[3]},player,event);
+ });
+ return ui.create.dialog('惊惧',[vcards,'vcard'],'hidden');
+ },
+ check:function(button){
+ if(get.event().getParent().type!='phase') return 1;
+ return get.player().getUseValue({name:button.link[2],nature:button.link[3]});
+ },
+ backup:function(links,player){
+ return {
+ filterCard:()=>false,
+ viewAs:{
+ name:links[0][2],
+ nature:links[0][3],
+ isCard:true,
+ },
+ selectCard:-1,
+ precontent(){
+ 'step 0'
+ player.moveCard(`惊惧:将其他角色判定区里的牌移动至你的判定区`,game.filterPlayer(i=>i!=player),player,card=>{
+ return get.position(card)=='j';
+ }).set('logSkill','jsrgjingju');
+ 'step 1'
+ if(result.bool){
+ delete event.result.skill;
+ }
+ else{
+ event.getParent().jsrgjingju=true;
+ event.getParent().goto(0);
+ delete event.getParent().openskilldialog;
+ event.finish();
+ }
+ 'step 2'
+ game.delayx();
+ },
+ }
+ },
+ prompt:function(links,player){
+ return '选择'+get.translation(links[0][3]||'')+'【'+get.translation(links[0][2])+'】的目标';
+ }
+ },
+ ai:{
+ order:function(){
+ const player=get.player(),event=_status.event;
+ if(player.canMoveCard(null,false,game.filterPlayer(),player,card=>{
+ return get.position(card)=='j';
+ })){
+ if(event.type=='dying'){
+ if(event.filterCard({name:'tao'},player,event)){
+ return 0.5;
+ }
+ }
+ else{
+ if(event.filterCard({name:'tao'},player,event)||event.filterCard({name:'shan'},player,event)){
+ return 4;
+ }
+ if(event.filterCard({name:'sha'},player,event)){
+ return 2.9;
+ }
+ }
+ }
+ return 0;
+ },
+ save:true,
+ respondSha:true,
+ respondShan:true,
+ skillTagFilter:function(player,tag,arg){
+ return player.canMoveCard(null,false,game.filterPlayer(),player,card=>{
+ return get.position(card)=='j';
+ })
+ },
+ result:{
+ player:function(player){
+ if(get.event().type=='dying'){
+ return get.attitude(player,get.event().dying);
+ }
+ return 1;
+ }
+ }
+ }
+ },
+ jsrgweizhui:{
+ audio:2,
+ trigger:{global:'phaseJieshuBegin'},
+ zhuSkill:true,
+ direct:true,
+ filter(event,player){
+ return player!=event.player&&event.player.group=='wei'&&event.player.isIn()&&player.hasZhuSkill('jsrgweizhui',event.player);
+ },
+ async content(event,trigger,player){
+ const {result:{bool,cards}}=await trigger.player.chooseCard(`是否响应${get.translation(player)}的主公技【危坠】?`,'将一张黑色手牌当【过河拆桥】对其使用',(card,player)=>{
+ if(get.color(card)!='black') return false;
+ return player.canUse(get.autoViewAs({name:'guohe'},[card]),get.event('target'));
+ }).set('target',player).set('ai',card=>{
+ if(get.effect(get.event('target'),get.autoViewAs({name:'guohe'},[card]),player)<=0) return 0;
+ return 6-get.value(card);
+ });
+ if(bool){
+ trigger.player.logSkill('jsrgweizhui',player);
+ trigger.player.useCard(get.autoViewAs({name:'guohe'},cards),cards,player);
+ }
+ },
+ },
+ //孙峻
+ jsrgyaoyan:{
+ audio:2,
+ trigger:{player:'phaseZhunbeiBegin'},
+ prompt:'是否发动【邀宴】?',
+ logTarget:()=>game.filterPlayer(),
+ async content(event,trigger,player){
+ const targets=game.filterPlayer();
+ const toDebateList=[];
+ while(targets.length){
+ const current=targets.shift();
+ const {result:{bool}}=await current.chooseBool(`是否响应${get.translation(player)}的【邀宴】,于回合结束参与议事?`).set('ai',()=>Math.random()<0.5);
+ if(bool){
+ toDebateList.add(current);
+ current.popup('同意','wood');
+ game.log(current,'#g同意','参加',player,'的议事');
+ }
+ else{
+ current.popup('拒绝','fire');
+ game.log(current,'#r拒绝','参加',player,'的议事');
+ }
+ }
+ if(toDebateList.length){
+ player.addTempSkill('jsrgyaoyan_hold');
+ player.markAuto('jsrgyaoyan_hold',toDebateList);
+ }
+ },
+ subSkill:{
+ hold:{
+ trigger:{player:'phaseEnd'},
+ charlotte:true,
+ forced:true,
+ popup:false,
+ onremove:true,
+ filter(event,player){
+ return player.getStorage('jsrgyaoyan_hold').some(i=>i.isIn());
+ },
+ async content(event,trigger,player){
+ player.chooseToDebate(player.getStorage('jsrgyaoyan_hold').filter(i=>i.isIn())).set('callback',async event=>{
+ const {bool,opinion,targets}=event.debateResult;
+ if(bool&&opinion){
+ if(opinion=='red'){
+ const notDebated=game.filterPlayer().removeArray(targets);
+ if(notDebated.length){
+ const {result}=await player.chooseTarget('获得任意名未议事的角色的各一张手牌',[1,Infinity],true,(card,player,target)=>{
+ return get.event('targets').includes(target)&&target.countGainableCards(player,'h');
+ }).set('targets',notDebated).set('ai',target=>{
+ const player=get.player();
+ const att=get.attitude(player,target);
+ return -att;
+ });
+ if(result.bool){
+ const targets=result.targets;
+ targets.sortBySeat();
+ player.line(targets,'green');
+ for(const current of targets){
+ await player.gainPlayerCard(current,'h',true);
+ }
+ }
+ }
+ }
+ else{
+ const {result:{bool,targets:targets2}}=await player.chooseTarget('是否对一名议事的角色造成2点伤害?',(card,player,target)=>{
+ return get.event('targets').includes(target);
+ }).set('targets',targets).set('ai',target=>{
+ const player=get.player();
+ const eff=get.damageEffect(target,player,player);
+ return eff;
+ });
+ if(bool){
+ player.line(targets2[0]);
+ targets2[0].damage(2);
+ }
+ }
+ }
+ });
+ },
+ }
+ }
+ },
+ jsrgbazheng:{
+ audio:2,
+ trigger:{global:'debateShowOpinion'},
+ filter(event,player){
+ if(!event.targets.includes(player)) return false;
+ const damagedPlayers=player.getHistory('sourceDamage').map(evt=>evt.player).toUniqued();
+ let dissent;
+ const colors=['red','black'];
+ for(const color of colors){
+ if(event[color].some(i=>i[0]==player)){
+ dissent=colors.find(i=>i!=color);
+ break;
+ }
+ }
+ return event[dissent].some(i=>damagedPlayers.includes(i[0]));
+ },
+ forced:true,
+ locked:false,
+ direct:true,
+ async content(event,trigger,player){
+ let myOpinion,dissent;
+ const colors=['red','black'];
+ for(const color of colors){
+ if(trigger[color].some(i=>i[0]==player)){
+ myOpinion=color;
+ dissent=colors.find(i=>i!=color);
+ break;
+ }
+ }
+ const damagedPlayers=player.getHistory('sourceDamage').map(evt=>evt.player).toUniqued();
+ let dissident=[];
+ for(let i=0;iget.suit(card)=='heart')){
+ const owners=trigger.cards.filter((card=>get.suit(card)=='heart')).map(card=>get.owner(card)).toUniqued();
+ for(const owner of owners){
+ if(owner&&owner.isIn()) await owner.recover();
+ }
+ }
+ if(trigger.player==player) return;
+ player.addTempSkill('jsrgdanxin_distance');
+ if(!player.storage.jsrgdanxin_distance) player.storage.jsrgdanxin_distance={};
+ const id=targets[0].playerid;
+ if(typeof player.storage.jsrgdanxin_distance[id]!='number') player.storage.jsrgdanxin_distance[id]=0;
+ player.storage.jsrgdanxin_distance[id]++;
+ player.markSkill('jsrgdanxin_distance');
+ },
+ },
+ distance:{
+ onremove:true,
+ charlotte:true,
+ mod:{
+ globalFrom(player,target,distance){
+ if(!player.storage.jsrgdanxin_distance) return;
+ const dis=player.storage.jsrgdanxin_distance[target.playerid];
+ if(typeof dis=='number') return distance+dis;
+ },
+ },
+ intro:{
+ content(storage,player){
+ if(!storage) return;
+ const map=(_status.connectMode?lib.playerOL:game.playerMap);
+ let str=`你本回合:`;
+ for(const id in storage){
+ str+='至'+get.translation(map[id])+'的距离+'+storage[id];
+ }
+ return str;
+ }
+ }
+ },
+ }
+ },
+ jsrgfengxiang:{
+ audio:'fengxiang',
+ trigger:{player:'damageEnd'},
+ forced:true,
+ direct:true,
+ filter(event,player){
+ return game.hasPlayer(current=>{
+ return current.countCards('e');
+ })
+ },
+ async content(event,trigger,player){
+ const {result:{bool,targets}}=await player.chooseTarget('封乡:与一名其他角色交换装备区里的所有牌',(card,player,target)=>{
+ return target.countCards('e')+player.countCards('e')>0&&player!=target;
+ },true).set('ai',target=>{
+ const player=get.player();
+ const att=get.attitude(player,target);
+ let delta=get.value(target.getCards('e'),player)-get.value(player.getCards('e'),player);
+ if(att>0){
+ if(delta<0) delta+=att/3;
+ }
+ else{
+ if(delta<0) delta-=att/3;
+ }
+ return delta;
+ });
+ if(bool){
+ player.logSkill('jsrgfengxiang',targets[0]);
+ const num=player.countCards('e');
+ await player.swapEquip(targets[0]);
+ const delta=num-player.countCards('e');
+ if(delta>0) player.draw(delta);
+ }
+ },
+ },
+ jsrgfuhai:{
+ audio:'xinfu_fuhai',
+ enable:'phaseUse',
+ usable:1,
+ filter(event,player){
+ return game.hasPlayer(current=>{
+ return current.countCards('h')&¤t!=player;
+ })
+ },
+ filterTarget(card,player,target){
+ return target.countCards('h')&&target!=player;
+ },
+ selectTarget:-1,
+ multitarget:true,
+ multiline:true,
+ async content(event,trigger,player){
+ const targets=event.targets.sortBySeat();
+ const next=player.chooseCardOL(targets,'请展示一张手牌',true).set('ai',card=>{
+ return -get.value(card);
+ }).set('aiCard',target=>{
+ const hs=target.getCards('h');
+ return {bool:true,cards:[hs.randomGet()]};
+ });
+ next._args.remove('glow_result');
+ const {result}=await next;
+ const cards=[];
+ const videoId=lib.status.videoId++;
+ for(let i=0;i{
+ var dialog=ui.create.dialog(get.translation(player)+'发动了【浮海】',cards);
+ dialog.videoId=id;
+ const getName=(target)=>{
+ if(target._tempTranslate) return target._tempTranslate;
+ var name=target.name;
+ if(lib.translate[name+'_ab']) return lib.translate[name+'_ab'];
+ return get.translation(name);
+ }
+ for(let i=0;iincrease){
+ increase=number;
+ flag=true;
+ }
+ else increase=Infinity;
+ if(numberget.event('choice')).set('choice',clock>anticlock?0:1)
+ player.draw(index==0?clock:anticlock);
+ },
+ ai:{
+ order:8,
+ result:{player:1},
+ }
+ },
+ //张嫙
+ jsrgtongli:{
+ audio:'tongli',
+ trigger:{player:'useCardToPlayered'},
+ filter(event,player){
+ if(!event.isFirstTarget) return false;
+ const type=get.type(event.card);
+ if(type!='basic'&&type!='trick') return false;
+ const hs=player.getCards('h');
+ if(!hs.length) return false;
+ const evt=event.getParent('phaseUse');
+ if(!evt||evt.player!=player) return false;
+ const num1=player.getHistory('useCard',evtx=>{
+ return evtx.getParent('phaseUse')==evt;
+ }).length;
+ if(hs.length{
+ let str='奢葬';
+ if(player==game.me&&!_status.auto){
+ str+=':获得任意张花色各不相同的牌';
+ }
+ const dialog=ui.create.dialog(str,cards);
+ dialog.videoId=id;
+ },player,videoId,cards);
+ const time=get.utc();
+ game.addVideo('showCards',player,['奢葬',get.cardsInfo(event.cards)]);
+ game.addVideo('delay',null,2);
+ const list=[];
+ for(const i of cards) list.add(get.suit(i,false));
+ const next=player.chooseButton([1,list.length]);
+ next.set('dialog',event.videoId);
+ next.set('filterButton',function(button){
+ for(var i=0;i0){
+ await game.asyncDelay(0,time2);
+ }
+ game.broadcastAll('closeDialog',videoId);
+ player.gain(result.links,'gain2');
+ }
+ },
+ },
+ jsrgchiying:{
+ audio:'dcchiying',
+ enable:'phaseUse',
+ usable:1,
+ filterTarget:true,
+ async content(event,trigger,player){
+ const target=event.target;
+ const targets=game.filterPlayer(current=>target.inRange(current)&¤t!=player).sortBySeat(player);
+ if(!targets.length) return;
+ while(targets.length){
+ const current=targets.shift();
+ if(current.countCards('he')) await current.chooseToDiscard('驰应:请弃置一张牌','he',true);
+ }
+ let cards=[];
+ game.getGlobalHistory('cardMove',evt=>{
+ if(evt.getParent(3)==event){
+ cards.addArray(evt.cards.filter(card=>get.type(card)=='basic'));
+ }
+ });
+ if(cards.length<=target.getHp()){
+ cards=cards.filterInD('d');
+ if(cards.length) target.gain(cards,'gain2');
+ }
+ },
+ ai:{
+ order:6,
+ result:{
+ target(player,target){
+ const targets=game.filterPlayer(current=>target.inRange(current)&¤t!=player);
+ let eff=0;
+ for(const targetx of targets){
+ let effx=get.effect(targetx,{name:'guohe_copy2'},player,target);
+ if(get.attitude(player,targetx)<0) effx/=2;
+ eff+=effx;
+ }
+ return eff*(get.attitude(player,target)<=0?0.75:1);
+ }
+ }
+ }
+ },
+ //郭照
+ jsrgpianchong:{
+ audio:'pianchong',
+ trigger:{global:'phaseJieshuBegin'},
+ filter(event,player){
+ return player.getHistory('lose').length;
+ },
+ frequent:true,
+ async content(event,trigger,player){
+ player.judge().set('callback',()=>{
+ const red=[],black=[];
+ game.getGlobalHistory('cardMove',evt=>{
+ if(evt.name!='cardsDiscard'){
+ if(evt.name!='lose'||evt.position!=ui.discardPile) return false;
+ }
+ const cards=evt.cards.filter(card=>get.position(card,true)=='d');
+ red.addArray(cards.filter(i=>get.color(i,false)=='red'));
+ black.addArray(cards.filter(i=>get.color(i,false)=='black'));
+ });
+ if(event.judgeResult.color=='red'&&red.length){
+ player.draw(red.length);
+ }
+ else if(event.judgeResult.color=='black'&&black.length){
+ player.draw(black.length);
+ }
+ })
+ },
+ },
+ jsrgzunwei:{
+ audio:'zunwei',
+ enable:'phaseUse',
+ usable:1,
+ filter(event,player){
+ const storage=player.getStorage('jsrgzunwei');
+ return storage.length<3&&game.hasPlayer(current=>{
+ return player.isDamaged()&¤t.getHp()>player.getHp()&&!storage.includes(2)||
+ current.countCards('h')>player.countCards('h')&&!storage.includes(0)||
+ current.countCards('e')>player.countCards('e')&&!storage.includes(1);
+ });
+ },
+ chooseButton:{
+ dialog(event,player){
+ const list=[
+ '选择手牌数大于你的一名角色',
+ '选择装备数大于你的一名角色',
+ '选择体力值大于你的一名角色',
+ ];
+ const choiceList=ui.create.dialog('尊位:请选择一项','forcebutton','hidden');
+ choiceList.add([list.map((item,i)=>{
+ if(player.getStorage('jsrgzunwei').includes(i)) item=`${item}`;
+ return [i,item];
+ }),'textbutton'])
+ return choiceList;
+ },
+ filter(button){
+ const player=get.player();
+ if(player.getStorage('jsrgzunwei').includes(button.link)) return false;
+ if(button.link==2){
+ if(!player.isDamaged()) return false;
+ return game.hasPlayer(current=>{
+ return current.getHp()>player.getHp();
+ });
+ }
+ if(button.link==0){
+ return game.hasPlayer(current=>{
+ return current.countCards('h')>player.countCards('h');
+ });
+ }
+ if(button.link==1){
+ return game.hasPlayer(current=>{
+ return current.countCards('e')>player.countCards('e');
+ });
+ }
+ },
+ backup(links){
+ const next=get.copy(lib.skill.jsrgzunwei.backups[links[0]]);
+ next.audio='zunwei';
+ next.filterCard=function(){return false};
+ next.selectCard=-1;
+ return next;
+ },
+ check(button){
+ const player=get.player();
+ switch(button.link){
+ case 2:{
+ const target=game.findPlayer(function(current){
+ return current.isMaxHp();
+ });
+ return (Math.min(target.hp,player.maxHp)-player.hp)*2;
+ }
+ case 0:{
+ const target=game.findPlayer(function(current){
+ return current.isMaxHandcard();
+ });
+ return Math.min(5,target.countCards('h')-player.countCards('h'))*0.8;
+ }
+ case 1:{
+ const target=game.findPlayer(function(current){
+ return current.isMaxEquip();
+ });
+ return (target.countCards('e')-player.countCards('e'))*1.4;
+ }
+ }
+ },
+ prompt(links){
+ return [
+ '选择一名手牌数大于你的其他角色,将手牌数摸至与其相同(至多摸五张)',
+ '选择一名装备区内牌数大于你的其他角色,将其装备区里的牌移至你的装备区,直到你装备数不小于其',
+ '选择一名体力值大于你的其他角色,将体力值回复至与其相同',
+ ][links[0]];
+ },
+ },
+ backups:[
+ {
+ filterTarget(card,player,target){
+ return target.countCards('h')>player.countCards('h');
+ },
+ async content(event,trigger,player){
+ player.draw(Math.min(5,event.target.countCards('h')-player.countCards('h')));
+ if(!player.storage.jsrgzunwei) player.storage.jsrgzunwei=[];
+ player.storage.jsrgzunwei.add(0);
+ },
+ ai:{
+ order:10,
+ result:{
+ player:function(player,target){
+ return Math.min(5,target.countCards('h')-player.countCards('h'));
+ },
+ },
+ },
+ },
+ {
+ filterTarget(card,player,target){
+ return target.countCards('e')>player.countCards('e');
+ },
+ async content(event,trigger,player){
+ if(!player.storage.jsrgzunwei) player.storage.jsrgzunwei=[];
+ player.storage.jsrgzunwei.add(1);
+ const target=event.target;
+ do{
+ if(!target.countCards('e',card=>{
+ return player.canEquip(card);
+ })) break;
+ const {result:{bool,links}}=await player.chooseButton([
+ `尊位:将${get.translation(target)}的一张装备牌移至你的区域内`,
+ target.getCards('e')
+ ],true).set('filterButton',button=>{
+ return get.player().canEquip(button.link);
+ }).set('ai',get.buttonValue);
+ if(bool){
+ target.$give(links[0],player,false);
+ await player.equip(links[0]);
+ }
+ }
+ while(player.countCards('e')player.hp;
+ },
+ async content(event,trigger,player){
+ player.recover(event.target.hp-player.hp);
+ if(!player.storage.jsrgzunwei) player.storage.jsrgzunwei=[];
+ player.storage.jsrgzunwei.add(2);
+ },
+ ai:{
+ order:10,
+ result:{
+ player:function(player,target){
+ return (Math.min(target.hp,player.maxHp)-player.hp);
+ },
+ },
+ },
+ },
+ ],
+ ai:{
+ order:10,
+ result:{
+ player:1,
+ },
+ },
+ subSkill:{
+ backup:{},
+ }
+ },
//江山如故·转
//404郭嘉
jsrgqingzi:{
@@ -935,7 +2813,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
ai1:function(card){
var player=get.player();
var maxVal=5.5;
- if(get.name(card,false)=='ying'&&player.hasSkill('jsrgchuaxin')) maxVal-=3;
+ if(get.name(card,false)=='ying'&&player.hasSkill('jsrgchuanxin')) maxVal-=3;
return maxVal-get.value(card);
},
precontent:function(){
@@ -6329,6 +8207,94 @@ game.import('character',function(lib,game,ui,get,ai,_status){
jsrg_fanjiangzhangda_prefix:'转',
jsrgfushan:'负山',
jsrgfushan_info:'出牌阶段开始时,所有其他角色可以依次交给你一张牌并令你此阶段使用【杀】的次数上限+1。此阶段结束时,若你使用【杀】的次数未达到上限且此阶段以此法交给你牌的角色均存活,你失去2点体力,否则你将手牌摸至体力上限。',
+ jsrg_zhugeliang:'梦诸葛亮',
+ jsrg_zhugeliang_prefix:'梦',
+ jsrgwentian:'问天',
+ jsrgwentian_info:'①你可以将牌堆顶的牌当【无懈可击】/【火攻】使用,若此牌不为黑色/红色,〖问天〗于本轮失效。②每回合限一次。你的一个阶段开始时,你可以观看牌堆顶的五张牌,然后将其中一张牌交给一名其他角色,将其余牌以任意顺序置于牌堆顶或牌堆底。',
+ jsrgchushi:'出师',
+ jsrgchushi_info:'出牌阶段限一次。若你不为主公,你可以与主公议事。若结果为:红色,你与其各摸一张牌,若你与其手牌数之和小于7,重复此流程;黑色,当你于本轮内造成属性伤害时,此伤害+1。',
+ jsrgyinlve:'隐略',
+ jsrgyinlve_info:'每轮各限一次。当一名角色受到火焰/雷电伤害时,你可以防止此伤害,然后于当前回合结束后执行一个只有摸牌/弃牌阶段的回合。',
+ jsrg_jiangwei:'合姜维',
+ jsrg_jiangwei_prefix:'合',
+ jsrgjinfa:'矜伐',
+ jsrgjinfa_info:'出牌阶段限一次。你可以展示一张手牌,然后令所有体力上限不大于你的角色议事。若结果与此牌颜色:相同,你令其中至多两名角色将手牌摸至体力上限;不同,你获得两张【影】。然后若没有其他角色与你意见相同,你可以变更势力。',
+ jsrgfumou:'复谋',
+ jsrgfumou_info:'魏势力技。当你议事结算结束后,与你意见不同的角色本回合不能使用或打出与其意见颜色相同的牌,你可以将一张【影】当【出其不意】对一名与你意见不同的角色使用。',
+ jsrgxuanfeng:'选锋',
+ jsrgxuanfeng_info:'蜀势力技。你可以将一张【影】当无距离和次数限制的刺【杀】使用。',
+ jsrg_luxun:'合陆逊',
+ jsrg_luxun_prefix:'合',
+ jsrgyoujin:'诱进',
+ jsrgyoujin_info:'出牌阶段开始时,你可以与一名角色拼点,你与其本回合不能使用或打出点数小于自己拼点牌的手牌,且赢的角色视为对没赢的角色使用一张【杀】。',
+ jsrgdailao:'待劳',
+ jsrgdailao_info:'出牌阶段,若你没有可以使用的手牌,你可以展示所有手牌并摸两张牌,然后结束此回合。',
+ jsrgzhubei:'逐北',
+ jsrgzhubei_info:'锁定技。①当你对本回合受到过伤害的角色造成伤害时,此伤害+1。②你对本回合失去过最后手牌的角色使用牌无次数限制。',
+ jsrg_zhaoyun:'合赵云',
+ jsrg_zhaoyun_prefix:'合',
+ jsrglonglin:'龙临',
+ jsrglonglin_info:'其他角色于其出牌阶段内首次使用【杀】指定第一个目标后,你可以弃置一张牌令此【杀】无效,然后其可以视为对你使用一张【决斗】,你以此法造成伤害后,其本阶段不能再使用手牌。',
+ jsrgzhendan:'镇胆',
+ jsrgzhendan_info:'①你可以将一张非基本手牌当任意基本牌使用或打出。②当你受到伤害后,你摸X张牌并令该技能本轮失效(X为本轮所有角色执行过的回合数且至多为5)。③一轮游戏开始时,若上一轮该技能未因〖镇胆②〗失效过,你摸Y张牌(Y为上一轮所有角色执行过的回合数且至多为5)。',
+ jsrg_simayi:'合司马懿',
+ jsrg_simayi_prefix:'合',
+ jsrgyingshi:'鹰眎',
+ jsrgyingshi_info:'当你翻面时,你可以观看牌堆底的三张牌(若死亡角色数大于2则改为五张),然后将其中任意数量的牌以任意顺序置于牌堆顶,其余以任意顺序置于牌堆底。',
+ jsrgtuigu:'蜕骨',
+ jsrgtuigu_info:'①回合开始时,你可以翻面并令你本回合的手牌上限+X,然后摸X张牌并视为使用一张【解甲归田】(X为存活角色数的一半,向下取整),目标角色不能使用以此法得到的牌直到其回合结束。②一轮游戏开始时,若你上一轮未执行过回合,你获得一个额外的回合。③当你失去装备牌里的牌后,你回复1点体力。',
+ jsrg_guoxun:'合郭循',
+ jsrg_guoxun_prefix:'合',
+ jsrgeqian:'遏前',
+ jsrgeqian_info:'①结束阶段,你可以蓄谋任意次。②当你使用【杀】或蓄谋牌指定其他角色为唯一目标后,你可以令此牌不计入次数限制并获得目标一张牌,然后其可以令你本回合至其的距离+2。',
+ jsrgfusha:'伏杀',
+ jsrgfusha_info:'限定技。出牌阶段,若你的攻击范围内仅有一名角色,你可以对其造成X点伤害(X为你的攻击范围,至多为游戏人数)。',
+ jsrg_sunlubansunluyu:'合孙鲁班孙鲁育',
+ jsrg_sunlubansunluyu_prefix:'合',
+ jsrgdaimou:'殆谋',
+ jsrgdaimou_info:'每回合各限一次。当一名角色使用【杀】指定其他角色/你为目标时,你可以用牌堆顶的牌蓄谋/你须弃置你区域里的一张蓄谋牌。',
+ jsrgfangjie:'芳洁',
+ jsrgfangjie_info:'准备阶段,若你没有蓄谋牌,你回复1点体力并摸一张牌,否则你可以弃置你区域里的任意张蓄谋牌并失去〖芳洁〗。',
+ jsrg_caofang:'合曹芳',
+ jsrg_caofang_prefix:'合',
+ jsrgzhaotu:'诏图',
+ jsrgzhaotu_info:'每轮限一次。你可以将一张红色非锦囊牌当【乐不思蜀】使用,然后当前回合结束后,目标执行一个手牌上限-2的额外回合。',
+ jsrgjingju:'惊惧',
+ jsrgjingju_info:'当你需要使用任意一种基本牌时,你可以将其他角色判定区里的一张牌移动至你的判定区,视为你使用之。',
+ jsrgweizhui:'危坠',
+ jsrgweizhui_info:'主公技。其他魏势力角色的结束阶段,其可以将一张黑色手牌当【过河拆桥】对你使用。',
+ jsrg_sunjun:'合孙峻',
+ jsrg_sunjun_prefix:'合',
+ jsrgyaoyan:'邀宴',
+ jsrgyaoyan_info:'准备阶段,你可以令所有角色依次选择是否于回合结束时议事,若议事结果为:红色,你获得任意名未议事的角色各一张手牌;黑色,你可以对一名议事的角色造成2点伤害。',
+ jsrgbazheng:'霸政',
+ jsrgbazheng_info:'当你参与的议事展示意见时,本回合受到过你伤害的角色意见视为与你相同。',
+ jsrg_liuyong:'合刘永',
+ jsrg_liuyong_prefix:'合',
+ jsrgdanxin:'丹心',
+ jsrgdanxin_info:'你可以将一张牌当【推心置腹】使用,你展示以此法交出与得到的牌,以此法得到♥牌的角色回复1点体力,然后你至目标角色的距离+1直到回合结束。',
+ jsrgfengxiang:'封乡',
+ jsrgfengxiang_info:'锁定技。当你受到伤害后,你与一名其他角色交换装备区里的所有牌。若你装备区里的牌因此减少,你摸等同于减少牌数的牌。',
+ jsrg_weiwenzhugezhi:'合卫温诸葛直',
+ jsrg_weiwenzhugezhi_prefix:'合',
+ jsrgfuhai:'浮海',
+ jsrgfuhai_info:'出牌阶段限一次。你可以令所有有手牌的其他角色同时展示一张手牌,然后你选择一个方向并摸X张牌(X为该方向上的角色展示的点数连续严格递增或严格递减的牌数,至少为1)。',
+ jsrg_zhangxuan:'合张嫙',
+ jsrg_zhangxuan_prefix:'合',
+ jsrgtongli:'同礼',
+ jsrgtongli_info:'当你于出牌阶段内使用基本牌或普通锦囊牌指定第一个目标后,若你手牌中的花色数和你于本阶段内使用过的牌数相等,则你可以展示所有手牌,令此牌额外结算一次。',
+ jsrgshezang:'奢葬',
+ jsrgshezang_info:'每轮限一次。当你或你回合内的其他角色进入濒死状态时,你可以亮出牌堆顶的四张牌,获得其中任意张花色各不相同的牌。',
+ jsrg_gaoxiang:'合高翔',
+ jsrg_gaoxiang_prefix:'合',
+ jsrgchiying:'驰应',
+ jsrgchiying_info:'出牌阶段限一次。你可以选择一名角色,令其攻击范围内的其他角色依次弃置一张牌。若以此法弃置的基本牌数不大于其体力值,其获得这些基本牌。',
+ jsrg_guozhao:'合郭照',
+ jsrg_guozhao_prefix:'合',
+ jsrgpianchong:'偏宠',
+ jsrgpianchong_info:'一名角色的结束阶段,若你于此回合内失去过牌,你可以判定。若结果为红色/黑色,你摸此回合进入弃牌堆的红色/黑色牌数量的牌。',
+ jsrgzunwei:'尊位',
+ jsrgzunwei_info:'出牌阶段限一次。你可以选择一名其他角色并选择执行一项,然后移除该选项:1.将手牌数摸至与该角色相同(最多摸五张);2.将其装备牌移至你的装备区,直到你装备区的牌数不少于其;3.将体力值回复至与该角色相同。',
xumou_jsrg:'蓄谋',
xumou_jsrg_info:'“蓄谋”牌可在判定区内重复存在。判定阶段开始时,你选择一项:⒈使用此牌对应的实体牌,然后本阶段不能再使用此牌名的牌;⒉将所有的“蓄谋”牌置入弃牌堆。',
@@ -6336,6 +8302,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
jiangshanrugu_qi:'江山如故·起',
jiangshanrugu_cheng:'江山如故·承',
jiangshanrugu_zhuan:'江山如故·转',
+ jiangshanrugu_he:'江山如故·合',
},
};
});
diff --git a/character/mobile.js b/character/mobile.js
index 07b1b1fe0..37218e870 100644
--- a/character/mobile.js
+++ b/character/mobile.js
@@ -15391,7 +15391,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
zhanggong:['zhanggong','re_zhanggong'],
baosanniang:['xin_baosanniang','re_baosanniang','baosanniang'],
heqi:['re_heqi','heqi'],
- weiwenzhugezhi:['weiwenzhugezhi','re_weiwenzhugezhi'],
+ weiwenzhugezhi:['weiwenzhugezhi','re_weiwenzhugezhi','jsrg_weiwenzhugezhi'],
xugong:['xugong','re_xugong','jsrg_xugong'],
liuzan:['re_liuzan','liuzan'],
sufei:['yj_sufei','sp_sufei','xf_sufei'],
diff --git a/character/offline.js b/character/offline.js
index 97b416cd8..088f1832a 100644
--- a/character/offline.js
+++ b/character/offline.js
@@ -886,25 +886,39 @@ game.import('character',function(lib,game,ui,get,ai,_status){
},
pshengwu:{
audio:'hengwu',
+ mod:{
+ aiOrder:(player,card,num)=>{
+ if(num>0&&get.tag(card,'draw')&&ui.cardPile.childNodes.length+ui.discardPile.childNodes.length<20) return 0;
+ },
+ aiValue:(player,card,num)=>{
+ if(num>0&&card.name==='zhuge') return 20;
+ },
+ aiUseful:(player,card,num)=>{
+ if(num>0&&card.name==='zhuge') return 10;
+ }
+ },
trigger:{player:['useCard','respond']},
direct:true,
+ locked:false,
filter:function(event,player){
return game.hasPlayer(i=>i.countCards('ej',cardx=>get.type(cardx)=='equip'&&get.suit(event.card)==get.suit(cardx)));
},
content:function(){
'step 0'
- var suit=get.suit(trigger.card);
- var prompt2='弃置任意张'+get.translation(suit)+'手牌,然后摸X张牌(X为你弃置的牌数+'+game.filterPlayer().map(i=>i.countCards('ej',cardx=>get.type(cardx)=='equip'&&get.suit(trigger.card)==get.suit(cardx))).reduce((p,c)=>p+c)+')';
+ var suit=get.suit(trigger.card),extra=game.filterPlayer().map(i=>i.countCards('ej',cardx=>{
+ return get.type(cardx)=='equip'&&get.suit(trigger.card)==get.suit(cardx);
+ })).reduce((p,c)=>p+c);
+ var prompt2='弃置任意张'+get.translation(suit)+'手牌,然后摸X张牌(X为你弃置的牌数+'+extra+')';
player.chooseToDiscard('h',[1,player.countCards('h',{suit:suit})],{suit:suit}).set('prompt',get.prompt('pshengwu')).set('prompt2',prompt2).set('ai',card=>{
- var player=_status.event.player;
+ if(_status.event.tie) return 0;
+ let player=_status.event.player;
if(_status.event.goon) return 12-get.value(card);
- if(player.countCards('h')>50) return 0;
if(player==_status.currentPhase){
if(['shan','caochuan','tao','wuxie'].includes(card.name)) return 8-get.value(card);
return 6-get.value(card);
}
return 5.5-get.value(card);
- }).set('goon',player.countCards('h',{suit:suit})==1).set('logSkill','pshengwu');
+ }).set('goon',player.countCards('h',{suit:suit})==1).set('tie',extra>ui.cardPile.childNodes.length+ui.discardPile.childNodes.length).set('logSkill','pshengwu');
'step 1'
if(result.bool){
var num=result.cards.length;
@@ -2649,7 +2663,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
},
ai:{
order:function(item,player){
- var num=player.getStorage('zyquanji').length;
+ var num=player.getExpansions('zyquanji').length;
if(num==1) return 8;
return 1;
},
diff --git a/character/rank.js b/character/rank.js
index 15033c82b..6a0e44615 100644
--- a/character/rank.js
+++ b/character/rank.js
@@ -987,6 +987,7 @@ window.noname_character_rank={
'libai',
'tw_gongsunfan',
'yue_caiwenji',
+ 'yue_xiaoqiao',
'vtb_xiaole',
'vtb_xiaojiu',
'ol_zhangzhang',
@@ -1817,6 +1818,7 @@ window.noname_character_rank={
'caoxian',
],
epic:[
+ 'yue_xiaoqiao',
'mb_chengui',
'ol_pengyang',
'ol_luyusheng',
diff --git a/character/refresh.js b/character/refresh.js
index 4e75e2c6a..71930bb29 100755
--- a/character/refresh.js
+++ b/character/refresh.js
@@ -6656,7 +6656,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
},
ai:{
order:function(item,player){
- var num=player.getStorage('gzquanji').length;
+ var num=player.getExpansions('gzquanji').length;
if(num==1) return 8;
return 1;
},
diff --git a/character/sb.js b/character/sb.js
index 8950fa6d1..be73a07b3 100644
--- a/character/sb.js
+++ b/character/sb.js
@@ -709,7 +709,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
audio:'sbkanpo',
trigger:{global:'useCard'},
filter:function(event,player){
- return event.player!=player&&player.getStorage('sbkanpo').includes(event.card.name);
+ return event.player!=player&&player.storage.sbkanpo[1].includes(event.card.name);
},
prompt2:function(event,player){
return '移除'+get.translation(event.card.name)+'的记录,令'+get.translation(event.card)+'无效';
diff --git a/character/shenhua.js b/character/shenhua.js
index 34750ef38..222262139 100755
--- a/character/shenhua.js
+++ b/character/shenhua.js
@@ -3667,7 +3667,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
target:function(card,player,target,current){
if(typeof card==='object'&&get.name(card)==='sha'&&target.mayHaveShan(player,'use')) return [0.6,0.75];
if(!target.hasFriend()&&!player.hasUnknown()) return;
- if(_status.currentPhase==target) return;
+ if(_status.currentPhase==target||get.type(card)==='delay') return;
if(card.name!='shuiyanqijunx'&&get.tag(card,'loseCard')&&target.countCards('he')){
if(target.hasSkill('ziliang')) return 0.7;
return [0.5,Math.max(2,target.countCards('h'))];
@@ -7714,7 +7714,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
dongzhuo:['dongzhuo','ol_dongzhuo','re_dongzhuo','sp_dongzhuo','yj_dongzhuo'],
dengai:['dengai','ol_dengai','re_dengai'],
sp_ol_zhanghe:['sp_ol_zhanghe','yj_zhanghe','sp_zhanghe','jsrg_zhanghe'],
- jiangwei:['jiangwei','ol_jiangwei','re_jiangwei','sb_jiangwei'],
+ jiangwei:['jiangwei','ol_jiangwei','re_jiangwei','sb_jiangwei','jsrg_jiangwei'],
liushan:['liushan','ol_liushan','re_liushan'],
sunce:['sunce','re_sunce','re_sunben','sb_sunce'],
zhangzhang:['zhangzhang','ol_zhangzhang','re_zhangzhang'],
diff --git a/character/sp.js b/character/sp.js
index 69ad799e9..5627da30a 100755
--- a/character/sp.js
+++ b/character/sp.js
@@ -727,7 +727,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
var {result:{bool,targets}}=await player.chooseTarget(get.prompt2('olgongjie'),[1,num],lib.filter.notMe).set('ai',target=>get.attitude(_status.event.player,target));
if(!bool) return;
targets=targets.sortBySeat();
- player.logSkill('gongjie',targets);
+ player.logSkill('olgongjie',targets);
for(var target of targets){
var {result:{bool,cards}}=await target.gainPlayerCard(player,true,'he');
if(bool) draws.add(get.suit(cards[0],player));
@@ -788,6 +788,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){
return player.countCards('he');
},
direct:true,
+ limited:true,
+ skillAnimation:true,
+ animationColor:'water',
async content(event,trigger,player){
var target=_status.currentPhase,num=player.countCards('he');
var {result:{bool,cards}}=await player.chooseToGive(get.prompt2('olxiangzuo',target),[1,num],'he').set('ai',card=>{
@@ -951,7 +954,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
forced:true,
content:function(){
'step 0'
- player.addTempSkill('olsilv'+(trigger.getg?'gain':'lose'));
+ player.addTempSkill('olsilv_'+(trigger.getg?'gain':'lose'));
if(!trigger.visible){
var cards,name=player.storage.ollianju;
if(trigger.getg) cards=trigger.getg(player).filter(card=>card.name==name);
@@ -13357,7 +13360,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
audio:2,
direct:true,
filter:function(event,player){
- return player!=event.player&&!event.player.isDisabledJudge()&&event.player.countCards('he')&&!event.player.countCards('j');
+ return player!=event.player&&!event.player.isDisabledJudge()&&event.player.countCards('he')&&!event.player.countCards('j',{type:'delay'});
},
content:function(){
'step 0'
@@ -26329,7 +26332,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
retuogu:'托孤',
retuogu_info:'一名角色死亡时,你可以令其选择其武将牌上的一个技能(主公技,限定技,觉醒技,隐匿技、使命技等特殊技能除外),然后你获得其选择的技能并失去上次因〖托孤〗获得的技能。',
shanzhuan:'擅专',
- shanzhuan_info:'当你对其他角色造成伤害后,若其判定区没有牌,则你可以将其的一张牌置于其的判定区。若此牌不为延时锦囊牌且此牌为:红色,此牌视为【乐不思蜀】;黑色,此牌视为【兵粮寸断】。回合结束时,若你本回合内未造成伤害,你可摸一张牌。',
+ shanzhuan_info:'①当你对其他角色造成伤害后,若其判定区没有延时类锦囊牌,则你可以将其的一张牌置于其的判定区。若此牌不为延时锦囊牌且此牌为:红色,此牌视为【乐不思蜀】;黑色,此牌视为【兵粮寸断】。②回合结束时,若你本回合内未造成伤害,你可摸一张牌。',
spniluan:'逆乱',
spniluan_info:'出牌阶段,你可以将一张黑色牌当做【杀】使用。此【杀】使用结算完成后,若你未因此【杀】造成过伤害,则你令此【杀】不计入使用次数。',
spweiwu:'违忤',
diff --git a/character/sp2.js b/character/sp2.js
index a43f80794..0acd2355c 100644
--- a/character/sp2.js
+++ b/character/sp2.js
@@ -451,6 +451,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
trigger:{player:'phaseEnd',global:'die'},
filter:function(event,player){
if(event.name=='phase') return player.hasMark('starpizhi');
+ if(!player.getStorage('starcanxi_wangsheng').includes(event.player.group)&&!player.getStorage('starcanxi_xiangsi').includes(event.player.group)) return false;
var groups=player.getSkills().filter(skill=>skill.indexOf('starcanxi_')==0);
groups=groups.map(group=>group.slice(10));
return groups.includes(event.player.group);
@@ -11181,7 +11182,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
starcanxi_cancel:'向死',
starcanxi_info:'锁定技。游戏开始时,你获得场上所有角色的势力对应的“玺角”标记,然后选择一个“玺角”对应势力并选择以下一项;一轮开始时,你选择一个“玺角”对应势力并选择以下一项:①妄生:本轮被选择势力角色每回合首次造成的伤害+1且计算与其他角色间的距离-1;②向死:本轮其他被选择势力角色每回合首次回复体力后失去1点体力且每回合对你使用的第一张牌无效。',
starpizhi:'圮秩',
- starpizhi_info:'锁定技。①一名角色死亡后,若你拥有该角色对应的“玺角”标记,你失去之并摸X张牌。②结束阶段,你摸X张牌。(X为你本局游戏失去的“玺角”标记数)',
+ starpizhi_info:'锁定技。①一名角色死亡后,若你拥有该角色对应的“玺角”标记且你本轮发动〖向死〗的势力与其相同,你失去之并摸X张牌。②结束阶段,你摸X张牌。(X为你本局游戏失去的“玺角”标记数)',
starzhonggu:'冢骨',
starzhonggu_info:'主公技,锁定技。摸牌阶段,若游戏轮数大于等于场上的群势力角色数,则你额外摸两张牌,否则你少摸一张牌。',
star_dongzhuo:'星董卓',
diff --git a/character/standard.js b/character/standard.js
index a026971f6..913afa23f 100755
--- a/character/standard.js
+++ b/character/standard.js
@@ -1,4 +1,4 @@
-'use strict';
+import { game } from '../noname.js';
game.import('character',function(lib,game,ui,get,ai,_status){
return {
name:'standard',
@@ -93,6 +93,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){
ganning:['lingtong','xf_sufei'],
guanyu:['zhangfei','liaohua'],
},
+ /**
+ * @type { { [key: string]: Skill } }
+ */
skill:{
//标准版甘夫人
stdshushen:{
@@ -304,7 +307,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
logTarget:'source',
preHidden:true,
filter(event,player){
- return (event.source&&event.source.countGainableCards(player,event.source!=player?'he':'e')&&event.num>0);
+ return event.source&&event.source.countGainableCards(player,event.source!=player?'he':'e')>0&&event.num>0;
},
async content(event,trigger,player){
player.gainPlayerCard(true,trigger.source,trigger.source!=player?'he':'e');
@@ -1761,9 +1764,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){
},
async content(event,trigger,player){
event.count=trigger.getl(player).es.length;
- do {
+ while(event.count-->0){
player.draw(2);
- if(!player.hasSkill(event.name)) break;
+ if(!event.count||!player.hasSkill(event.name)) break;
if(!get.is.blocked(event.name,player)){
const chooseBoolEvent=player.chooseBool(get.prompt2('xiaoji')).set('frequentSkill','xiaoji');
chooseBoolEvent.ai=lib.filter.all;
@@ -1771,7 +1774,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
if(bool) player.logSkill('xiaoji');
else break;
}
- }while(event.count-->0);
+ }
},
ai:{
noe:true,
@@ -2325,7 +2328,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
characterReplace:{
caocao:['caocao','re_caocao','sb_caocao','dc_caocao'],
guojia:['guojia','re_guojia','ps1059_guojia','ps2070_guojia'],
- simayi:['simayi','re_simayi','ps_simayi','ps2068_simayi'],
+ simayi:['simayi','re_simayi','jsrg_simayi','ps_simayi','ps2068_simayi'],
jin_simayi:['jin_simayi','junk_simayi','ps_jin_simayi'],
zhenji:['zhenji','re_zhenji','sb_zhenji','yj_zhenji'],
xuzhu:['xuzhu','re_xuzhu'],
@@ -2335,15 +2338,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){
liubei:['liubei','re_liubei','sb_liubei','dc_liubei','junk_liubei'],
guanyu:['guanyu','re_guanyu','ps_guanyu','old_guanyu'],
zhangfei:['zhangfei','re_zhangfei','old_zhangfei','xin_zhangfei','sb_zhangfei','tw_zhangfei','jsrg_zhangfei','yj_zhangfei'],
- zhaoyun:['zhaoyun','re_zhaoyun','old_zhaoyun','sb_zhaoyun','ps2063_zhaoyun','ps2067_zhaoyun'],
+ zhaoyun:['zhaoyun','re_zhaoyun','old_zhaoyun','sb_zhaoyun','jsrg_zhaoyun','ps2063_zhaoyun','ps2067_zhaoyun'],
sp_zhaoyun:['sp_zhaoyun','jsp_zhaoyun'],
machao:['machao','re_machao','sb_machao','ps_machao'],
sp_machao:['sp_machao','dc_sp_machao','jsrg_machao','old_machao'],
- zhugeliang:['zhugeliang','re_zhugeliang','ps2066_zhugeliang','ps_zhugeliang','sb_zhugeliang'],
+ zhugeliang:['zhugeliang','re_zhugeliang','sb_zhugeliang','jsrg_zhugeliang','ps2066_zhugeliang','ps_zhugeliang'],
huangyueying:['huangyueying','re_huangyueying','junk_huangyueying','sb_huangyueying'],
sunquan:['sunquan','re_sunquan','sb_sunquan','dc_sunquan'],
zhouyu:['zhouyu','re_zhouyu','sb_zhouyu','ps1062_zhouyu','ps2080_zhouyu'],
- luxun:['luxun','re_luxun'],
+ luxun:['luxun','re_luxun','jsrg_luxun'],
lvmeng:['lvmeng','re_lvmeng','sb_lvmeng'],
huanggai:['huanggai','re_huanggai','sb_huanggai'],
daqiao:['daqiao','re_daqiao','sb_daqiao'],
diff --git a/character/tw.js b/character/tw.js
index dc2404dcd..bd06292b8 100644
--- a/character/tw.js
+++ b/character/tw.js
@@ -77,7 +77,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
tw_madai:['male','shu',4,['mashu','twqianxi']],
tw_niujin:['male','wei',4,['twcuorui','twliewei']],
tw_guanqiujian:['male','wei',3,['twzhengrong','twhongju']],
- tw_daxiaoqiao:['female','wu',3,['twxingwu','twpingting']],
+ tw_daxiaoqiao:['female','wu',3,['twxingwu','twpingting'],['tempname:daxiaoqiao']],
tw_furong:['male','shu',4,['twxuewei','twliechi']],
tw_yl_luzhi:['male','qun',3,['twmingren','twzhenliang']],
tw_liuzhang:['male','qun',3,['jutu','twyaohu','rehuaibi']],
@@ -364,12 +364,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){
event.target=target;
var list=['cancel2'];
var choiceList=[
- '弃置一张手牌,令此【杀】可以额外指定一个目标',
+ '令此【杀】可以额外指定一个目标',
'弃置其一张手牌,若此【杀】造成伤害,则你摸一张牌且本阶段可以额外使用一张【杀】',
];
if(target.countCards('h')) list.unshift('其弃置');
else choiceList[1]=''+choiceList[1]+'';
- if(game.hasPlayer(targetx=>!trigger.targets.includes(targetx)&&player.canUse(trigger.card,targetx))) list.unshift('你弃置');
+ if(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;
@@ -377,7 +377,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
var player=trigger.player;
var target=trigger.target;
if(controls.includes('其弃置')&&_status.event.goon) return '其弃置';
- if(controls.includes('你弃置')){
+ if(controls.includes('多指')){
if(game.hasPlayer(targetx=>!trigger.targets.includes(targetx)&&player.canUse(trigger.card,targetx)&&get.effect(targetx,trigger.card,player,player)>0)) return '你弃置';
}
return 'cancel2';
@@ -6240,7 +6240,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
audio:2,
trigger:{global:['roundStart','dying']},
init:function(player,skill){
- if(player.getExpansions('twxingwu').length) player.addAdditionalSkill(skill,['tianxiang_daxiaoqiao','liuli_daxiaoqiao']);
+ if(player.getExpansions('twxingwu').length) player.addAdditionalSkill(skill,['tianxiang','liuli']);
else player.removeAdditionalSkill(skill);
},
filter:function(event,player){
@@ -6269,18 +6269,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){
},
subSkill:{
update:{
- trigger:{
- player:['loseAfter','loseAsyncAfter','addToExpansionAfter'],
+ trigger:{player:['loseAfter','loseAsyncAfter','addToExpansionAfter']},
+ filter:function(event,player){
+ var cards=player.getExpansions('twxingwu'),skills=player.additionalSkills.twpingting;
+ return !((cards.length&&skills&&skills.length)||(!cards.length&&(!skills||!skills.length)));
},
forced:true,
silent:true,
- filter:function(event,player){
- var cards=player.getExpansions('twxingwu'),skills=player.additionalSkills.twpingting;
- if((cards.length&&skills&&skills.length)||(!cards.length&&(!skills||!skills.length))){
- return false;
- }
- return true;
- },
content:function(){
lib.skill.twpingting.init(player,'twpingting');
}
diff --git a/character/xianding.js b/character/xianding.js
index 41b0b18e6..a958de99c 100644
--- a/character/xianding.js
+++ b/character/xianding.js
@@ -20,7 +20,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
dc_sp_machao:['male','qun',4,['zhuiji','dc_olshichou']],
old_huangfusong:['male','qun',4,['xinfenyue']],
dc_xiahouba:['male','shu',4,['rebaobian']],
- dc_daxiaoqiao:['female','wu',3,['dcxingwu','dcluoyan']],
+ dc_daxiaoqiao:['female','wu',3,['dcxingwu','dcluoyan'],['tempname:daxiaoqiao']],
tianshangyi:['female','wei',3,['dcposuo','dcxiaoren']],
sunlingluan:['female','wu',3,['dclingyue','dcpandi']],
dc_wangjun:['male','qun',4,['dctongye','dcchangqu']],
@@ -145,10 +145,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){
return (dis?6:1)-get.useful(card);
}
if(_status.event.hvt.includes(card)){
- if(_status.event.suits.length>=4){
- if(cards.length>8) return 0;
- return 4.5-get.value(card);
- }
if(!_status.event.suits.includes(suit)) return 6-get.value(card);
if(card.name==='sha') return 3-get.value(card);
return 1-get.value(card);
@@ -1306,6 +1302,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){
},
dczhangcai:{
audio:2,
+ mod:{
+ aiOrder:(player,card,num)=>{
+ if(num>0&&get.tag(card,'draw')&&ui.cardPile.childNodes.length+ui.discardPile.childNodes.length<20) return 0;
+ },
+ aiValue:(player,card,num)=>{
+ if(num>0&&card.name==='zhuge') return 20;
+ },
+ aiUseful:(player,card,num)=>{
+ if(num>0&&card.name==='zhuge') return 10;
+ }
+ },
trigger:{
player:['useCard','respond'],
},
@@ -1319,7 +1326,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){
if(typeof num=='number') count=Math.max(1,player.countCards('h',card=>get.number(card)==num))
return '你可以摸'+get.cnNumber(count)+'张牌。';
},
+ check:(event,player)=>{
+ const num=player.hasSkill('dczhangcai_all')?get.number(event.card):8;
+ let count=1;
+ if(typeof num=='number') count=Math.max(1,player.countCards('h',card=>get.number(card)==num));
+ return ui.cardPile.childNodes.length+ui.discardPile.childNodes.length>=count;
+ },
frequent:true,
+ locked:false,
content:function(){
var num=player.hasSkill('dczhangcai_all')?get.number(trigger.card):8;
var count=1;
@@ -1649,33 +1663,29 @@ game.import('character',function(lib,game,ui,get,ai,_status){
}
},
},
- dcluoyan: {
- derivation: ['retianxiang', 'liuli'],
- init: function (player) {
- if (player.getStorage('dcxingwu').length) player.addAdditionalSkill('dcluoyan', ['retianxiang_daxiaoqiao', 'liuli_daxiaoqiao']);
+ dcluoyan:{
+ derivation:['retianxiang','liuli'],
+ init:function(player){
+ if(player.getExpansions('dcxingwu').length) player.addAdditionalSkill('dcluoyan',['retianxiang','liuli']);
else player.removeAdditionalSkill('dcluoyan');
},
- onremove: function (player) {
+ onremove:function(player){
player.removeAdditionalSkill('dcluoyan');
},
- trigger: {
- player: ['loseAfter', 'loseAsyncAfter', 'addToExpansionAfter'],
+ trigger:{player:['loseAfter','loseAsyncAfter','addToExpansionAfter']},
+ filter:function(event,player){
+ var cards=player.getExpansions('dcxingwu'),skills=player.additionalSkills.dcluoyan;
+ return !((cards.length&&skills&&skills.length)||(!cards.length&&(!skills||!skills.length)));
},
- filter: function (event, player) {
- var cards = player.getExpansions('dcxingwu'), skills = player.additionalSkills.dcluoyan;
- if ((cards.length && skills && skills.length) || (!cards.length && (!skills || !skills.length))) {
- return false;
- }
- return true;
- },
- forced: true,
- content: function () {
- lib.skill.twpingting.init(player, 'dcluoyan');
+ forced:true,
+ silent:true,
+ content:function(){
+ lib.skill.dcluoyan.init(player,'dcluoyan');
},
},
- retianxiang_daxiaoqiao: {
- audio: 'tianxiang_daxiaoqiao',
- inherit: 'retianxiang',
+ retianxiang_daxiaoqiao:{
+ audio:'tianxiang_daxiaoqiao',
+ inherit:'retianxiang',
},
//田尚衣
dcposuo:{
@@ -13514,7 +13524,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
fengfangnv:['fengfangnv','re_fengfangnv'],
luotong:['dc_luotong','luotong'],
dc_wangchang:['dc_wangchang','tw_wangchang'],
- guozhao:['guozhao','xin_guozhao'],
+ guozhao:['guozhao','xin_guozhao','jsrg_guozhao'],
dingshangwan:['dingshangwan','ol_dingshangwan'],
},
translate:{
diff --git a/game/asset.js b/game/asset.js
index f8670e51a..0d0ce7d8a 100644
--- a/game/asset.js
+++ b/game/asset.js
@@ -1,5 +1,5 @@
window.noname_asset_list=[
- 'v1.10.6',
+ 'v1.10.6.1',
/*audio start*/
'audio/background/aozhan_chaoming.mp3',
'audio/background/aozhan_online.mp3',
@@ -7237,30 +7237,41 @@ window.noname_asset_list=[
'image/character/jsp_liubei.jpg',
'image/character/jsp_zhaoyun.jpg',
'image/character/jsrg_caocao.jpg',
+ 'image/character/jsrg_caofang.jpg',
'image/character/jsrg_chendeng.jpg',
'image/character/jsrg_chunyuqiong.jpg',
'image/character/jsrg_dongbai.jpg',
'image/character/jsrg_fanjiangzhangda.jpg',
+ 'image/character/jsrg_gaoxiang.jpg',
'image/character/jsrg_guanyu.jpg',
'image/character/jsrg_guojia.jpg',
+ 'image/character/jsrg_guoxun.jpg',
+ 'image/character/jsrg_guozhao.jpg',
'image/character/jsrg_hansui.jpg',
'image/character/jsrg_hejin.jpg',
'image/character/jsrg_huangfusong.jpg',
'image/character/jsrg_huangzhong.jpg',
+ 'image/character/jsrg_jiangwei.jpg',
'image/character/jsrg_kongrong.jpg',
'image/character/jsrg_liubei.jpg',
'image/character/jsrg_liuhong.jpg',
'image/character/jsrg_liuyan.jpg',
+ 'image/character/jsrg_liuyong.jpg',
'image/character/jsrg_lougui.jpg',
+ 'image/character/jsrg_luxun.jpg',
'image/character/jsrg_lvbu.jpg',
'image/character/jsrg_machao.jpg',
'image/character/jsrg_nanhualaoxian.jpg',
'image/character/jsrg_pangtong.jpg',
'image/character/jsrg_qiaoxuan.jpg',
+ 'image/character/jsrg_simayi.jpg',
'image/character/jsrg_sunce.jpg',
'image/character/jsrg_sunjian.jpg',
+ 'image/character/jsrg_sunjun.jpg',
+ 'image/character/jsrg_sunlubansunluyu.jpg',
'image/character/jsrg_sunshangxiang.jpg',
'image/character/jsrg_wangyun.jpg',
+ 'image/character/jsrg_weiwenzhugezhi.jpg',
'image/character/jsrg_xiahouen.jpg',
'image/character/jsrg_xiahourong.jpg',
'image/character/jsrg_xugong.jpg',
@@ -7272,7 +7283,10 @@ window.noname_asset_list=[
'image/character/jsrg_zhanghe.jpg',
'image/character/jsrg_zhangliao.jpg',
'image/character/jsrg_zhangren.jpg',
+ 'image/character/jsrg_zhangxuan.jpg',
+ 'image/character/jsrg_zhaoyun.jpg',
'image/character/jsrg_zhenji.jpg',
+ 'image/character/jsrg_zhugeliang.jpg',
'image/character/jsrg_zhujun.jpg',
'image/character/jsrg_zoushi.jpg',
'image/character/jun_caocao.jpg',
diff --git a/game/game.js b/game/game.js
index 73ccd3c7e..04ba0207d 100644
--- a/game/game.js
+++ b/game/game.js
@@ -91,7 +91,7 @@ new Promise(resolve => {
script.async = true
script.onerror = (event) => {
console.error(event)
- const message = `您使用的浏览器或无名杀客户端加载内容失败!\n若您使用的客户端为自带内核的旧版“兼容版”,请及时更新客户端版本!\n若您使用的客户端为手机端的非兼容版无名杀,请尝试更新手机端WebView内核,或者更换为1.8.2版本以上的兼容版!`;
+ const message = `您使用的浏览器或《无名杀》客户端加载内容失败!\n若您使用的客户端为自带内核的旧版“兼容版”,请及时更新客户端版本!\n若您使用的客户端为手机端的非兼容版《无名杀》,请尝试更新手机的WebView内核,或者更换为1.8.2版本及以上的兼容版!\n若您是直接使用浏览器加载index.html进行游戏,请改为运行文件夹内的“noname-server.exe”(或使用VSCode等工具启动Live Server),以动态服务器的方式启动《无名杀》!`;
console.error(message);
alert(message);
exit()
diff --git a/game/update.js b/game/update.js
index 7c18fdd0b..4be954e40 100644
--- a/game/update.js
+++ b/game/update.js
@@ -1,137 +1,56 @@
window.noname_update={
- version:'1.10.6',
- update:'1.10.5',
+ version:'1.10.6.1',
+ update:'1.10.6',
changeLog:[
- '整合@nonameShijian @mengxinzxz @PZ157 @Ansolve @Rintim @S-N-O-R-L-A-X @universe-st @copcap @kuangshen04 的Pull Request',
- '拆分game.js,优化代码逻辑与可读性',
- '孙策(十周年斗地主)、乐小乔、手杀陈珪、手杀胡班、OL界凌统、OL界曹彰、OL界简雍、OL谋姜维、谋诸葛亮、谋关羽、曹宇、星董卓、曹宪、新杀谋鲁肃、新杀谋周瑜',
+ '整合@mengxinzxz @PZ157 @universe-st @Ansolve @Rintim @nonameShijian @copcap @kuangshen04 的Pull Request',
+ '《江山如故·合》武将包',
'其他AI优化与bug修复',
],
files:[
- 'card/extra.js',
- 'card/gujian.js',
- 'card/guozhan.js',
- 'card/gwent.js',
- 'card/hearth.js',
- 'card/huanlekapai.js',
- 'card/mtg.js',
- 'card/sp.js',
'card/standard.js',
- 'card/swd.js',
- 'card/yingbian.js',
'card/yongjian.js',
- 'card/yunchou.js',
- 'card/zhenfa.js',
- 'card/zhulu.js',
- 'character/clan.js',
- 'character/collab.js',
- 'character/ddd.js',
- 'character/diy.js',
'character/extra.js',
- 'character/gujian.js',
- 'character/gwent.js',
- 'character/hearth.js',
'character/huicui.js',
- 'character/jiange.js',
'character/jsrg.js',
'character/mobile.js',
- 'character/mtg.js',
'character/offline.js',
- 'character/old.js',
- 'character/onlyOL.js',
- 'character/ow.js',
'character/rank.js',
'character/refresh.js',
'character/sb.js',
'character/shenhua.js',
- 'character/shiji.js',
'character/sp.js',
'character/sp2.js',
'character/standard.js',
- 'character/swd.js',
'character/tw.js',
- 'character/xiake.js',
'character/xianding.js',
- 'character/xianjian.js',
- 'character/xinghuoliaoyuan.js',
- 'character/yijiang.js',
- 'character/yingbian.js',
- 'character/yxs.js',
-
- 'extension/boss/extension.js',
- 'game/codemirror.js',
- 'game/config.js',
- 'game/core-js-bundle.js',
- 'game/entry.js',
'game/game.js',
- 'game/package.js',
'game/source.js',
'mode/boss.js',
- 'mode/brawl.js',
- 'mode/chess.js',
- 'mode/doudizhu.js',
- 'mode/guozhan.js',
- 'mode/identity.js',
- 'mode/realtime.js',
- 'mode/single.js',
- 'mode/stone.js',
- 'mode/tafang.js',
- 'mode/versus.js',
'noname.js',
- 'noname/ai/basic.js',
- 'noname/ai/index.js',
'noname/game/index.js',
- 'noname/game/promises.js',
- 'noname/game/dynamic-style/index.js',
+
'noname/get/index.js',
'noname/get/is.js',
- 'noname/gnc/index.js',
- 'noname/gnc/is.js',
+
'noname/init/cordova.js',
'noname/init/import.js',
'noname/init/index.js',
- 'noname/init/node.js',
- 'noname/init/onload.js',
- 'noname/init/polyfill.js',
+
'noname/library/index.js',
- 'noname/library/path.js',
- 'noname/library/announce/index.d.ts',
- 'noname/library/announce/index.js',
- 'noname/library/channel/index.js',
- 'noname/library/element/button.js',
- 'noname/library/element/card.js',
- 'noname/library/element/client.js',
+
'noname/library/element/content.js',
- 'noname/library/element/contents.js',
- 'noname/library/element/control.js',
- 'noname/library/element/dialog.js',
'noname/library/element/gameEvent.js',
'noname/library/element/gameEventPromise.js',
- 'noname/library/element/index.js',
- 'noname/library/element/nodeWS.js',
- 'noname/library/element/player.js',
'noname/library/element/vcard.js',
- 'noname/library/experimental/index.js',
- 'noname/library/experimental/symbol.js',
- 'noname/library/init/index.js',
- 'noname/library/init/promises.js',
- 'noname/status/index.js',
+
'noname/ui/index.js',
- 'noname/util/browser.js',
- 'noname/util/config.js',
- 'noname/util/index.js',
- 'noname/util/mutex.js',
- 'noname/util/struct/index.js',
- 'noname/util/struct/interface/index.d.ts',
- 'noname/util/struct/interface/promise-error-handler.d.ts',
+
'noname/util/struct/promise-error-handler/chrome.js',
- 'noname/util/struct/promise-error-handler/firefox.js',
- 'noname/util/struct/promise-error-handler/index.js',
'noname/util/struct/promise-error-handler/unknown.js',
]
};
diff --git a/image/card/xumou_jsrg.jpg b/image/card/xumou_jsrg.jpg
index 109581254..2171863ec 100644
Binary files a/image/card/xumou_jsrg.jpg and b/image/card/xumou_jsrg.jpg differ
diff --git a/image/character/jsrg_caofang.jpg b/image/character/jsrg_caofang.jpg
new file mode 100644
index 000000000..c9260f90b
Binary files /dev/null and b/image/character/jsrg_caofang.jpg differ
diff --git a/image/character/jsrg_gaoxiang.jpg b/image/character/jsrg_gaoxiang.jpg
new file mode 100644
index 000000000..d2abd8ec8
Binary files /dev/null and b/image/character/jsrg_gaoxiang.jpg differ
diff --git a/image/character/jsrg_guoxun.jpg b/image/character/jsrg_guoxun.jpg
new file mode 100644
index 000000000..41868b5d3
Binary files /dev/null and b/image/character/jsrg_guoxun.jpg differ
diff --git a/image/character/jsrg_guozhao.jpg b/image/character/jsrg_guozhao.jpg
new file mode 100644
index 000000000..cf5826644
Binary files /dev/null and b/image/character/jsrg_guozhao.jpg differ
diff --git a/image/character/jsrg_jiangwei.jpg b/image/character/jsrg_jiangwei.jpg
new file mode 100644
index 000000000..29b66240e
Binary files /dev/null and b/image/character/jsrg_jiangwei.jpg differ
diff --git a/image/character/jsrg_liuyong.jpg b/image/character/jsrg_liuyong.jpg
new file mode 100644
index 000000000..57363374f
Binary files /dev/null and b/image/character/jsrg_liuyong.jpg differ
diff --git a/image/character/jsrg_luxun.jpg b/image/character/jsrg_luxun.jpg
new file mode 100644
index 000000000..0e74a3d3c
Binary files /dev/null and b/image/character/jsrg_luxun.jpg differ
diff --git a/image/character/jsrg_simayi.jpg b/image/character/jsrg_simayi.jpg
new file mode 100644
index 000000000..219bc25a1
Binary files /dev/null and b/image/character/jsrg_simayi.jpg differ
diff --git a/image/character/jsrg_sunjun.jpg b/image/character/jsrg_sunjun.jpg
new file mode 100644
index 000000000..659080375
Binary files /dev/null and b/image/character/jsrg_sunjun.jpg differ
diff --git a/image/character/jsrg_sunlubansunluyu.jpg b/image/character/jsrg_sunlubansunluyu.jpg
new file mode 100644
index 000000000..86656bc1a
Binary files /dev/null and b/image/character/jsrg_sunlubansunluyu.jpg differ
diff --git a/image/character/jsrg_weiwenzhugezhi.jpg b/image/character/jsrg_weiwenzhugezhi.jpg
new file mode 100644
index 000000000..6d591a206
Binary files /dev/null and b/image/character/jsrg_weiwenzhugezhi.jpg differ
diff --git a/image/character/jsrg_zhangxuan.jpg b/image/character/jsrg_zhangxuan.jpg
new file mode 100644
index 000000000..6e877f117
Binary files /dev/null and b/image/character/jsrg_zhangxuan.jpg differ
diff --git a/image/character/jsrg_zhaoyun.jpg b/image/character/jsrg_zhaoyun.jpg
new file mode 100644
index 000000000..1b7d747a2
Binary files /dev/null and b/image/character/jsrg_zhaoyun.jpg differ
diff --git a/image/character/jsrg_zhugeliang.jpg b/image/character/jsrg_zhugeliang.jpg
new file mode 100644
index 000000000..4b16a866b
Binary files /dev/null and b/image/character/jsrg_zhugeliang.jpg differ
diff --git a/index.html b/index.html
index ffa1fcf2b..abe49f125 100755
--- a/index.html
+++ b/index.html
@@ -7,7 +7,7 @@
无名杀
+
diff --git a/mode/boss.js b/mode/boss.js
index 9b01e7c20..36dabf984 100644
--- a/mode/boss.js
+++ b/mode/boss.js
@@ -8818,7 +8818,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
}
function isDefined(opd) {
if(opd!=undefined){
- if (opd.get||opd.set||opd.writable!=true||opd.configurable!=true||opd.enumerable!=true){
+ if (opd.get||opd.set||opd.writable!=true||opd.configurable!=true){
return true;
}
}
diff --git a/node_modules/noname-typings/Card.d.ts b/node_modules/noname-typings/Card.d.ts
new file mode 100644
index 000000000..07d0ce051
--- /dev/null
+++ b/node_modules/noname-typings/Card.d.ts
@@ -0,0 +1,23 @@
+declare type CardBaseUIData = {
+ name?: string;
+ suit?: string;
+ number?: number;
+ nature?: string;
+
+ //用于某些方法,用于过滤卡牌的额外结构
+ type?: string;
+ subtype?: string;
+ color?: string;
+
+ /**
+ * 是否时视为牌
+ *
+ * 是本来的卡牌,则为true,作为视为牌则为false/undefined
+ * 在useCard使用时,作为视为牌,会把next.cards,设置为card.cards;
+ *
+ */
+ isCard?: boolean;
+
+ /** 真实使用的卡牌 */
+ cards?: Card[];
+}
\ No newline at end of file
diff --git a/node_modules/noname-typings/Result.d.ts b/node_modules/noname-typings/Result.d.ts
new file mode 100644
index 000000000..24bfb85aa
--- /dev/null
+++ b/node_modules/noname-typings/Result.d.ts
@@ -0,0 +1,43 @@
+declare interface Result {
+ /**
+ * 最终结果
+ *
+ * 大多代表该事件到达这一步骤过程中的结果;
+ * 一般用来标记当前事件是否按预定执行的,即执行成功
+ *
+ * 大部分事件间接接触game.check,一般最终结果不变,大多数是这种
+ *
+ * 其实主要是ok方法会有直接的bool,主要涉及game.check;
+ */
+ bool?: boolean;
+
+ //choose系
+ /** 记录返回当前事件操作过程中的卡牌 */
+ cards: Card[];
+ /** 记录返回当前事件操作过程中的目标 */
+ targets: Player[];
+ /** 记录返回当前事件操作过程中的按钮 */
+ buttons: Button[];
+ /** 记录buttons内所有button.link(即该按钮的类型,link的类型很多,参考按钮的item) */
+ links: any[];
+
+ //control系(直接control系列没有result.bool)
+ /** control操作面板的选中结果,即该按钮的link,即名字 */
+ control: string;
+ /** 既control的下标 */
+ index: number;
+
+ //ok系
+ /** 记录返回当前事件操作过程中,面板按钮的确定ok取消cancel */
+ confirm: string;
+ /** 一般为触发的“视为”技能 */
+ skill: string;
+ /**
+ * 当前事件操作的“视为”牌,
+ * 当前有“视为”操作,该card参数特供给视为牌,不需要cards[0]获取视为牌 ;
+ * 判断是否为视为牌:card.isCard,false为视为牌
+ */
+ card: Card;
+
+ [key: string]: any;
+}
\ No newline at end of file
diff --git a/node_modules/noname-typings/Skill.d.ts b/node_modules/noname-typings/Skill.d.ts
new file mode 100644
index 000000000..9c1b70514
--- /dev/null
+++ b/node_modules/noname-typings/Skill.d.ts
@@ -0,0 +1,1820 @@
+/** 时机 */
+declare interface SkillTrigger {
+ /**
+ * 全场任意一名角色
+ *
+ * 代表所有人
+ */
+ global?: string | string[];
+ /**
+ * 玩家自己
+ *
+ * 触发时件中,技能拥有者为事件的发起者;
+ *
+ * 注:需要是自己引发的事件;
+ */
+ player?: string | string[];
+ /**
+ * 你自己成为目标时
+ */
+ target?: string | string[];
+ /**
+ * 来源是你自己时
+ */
+ source?: string | string[];
+}
+
+/**
+ * hookTrigger在不同方法中触发的方法接口
+ *
+ * 注:似乎时用于模式,作为,游戏全局的一些每次都需要触发的方法(算是不实用的一个接口)
+ */
+declare interface SkillHookTrigger {
+ /**
+ * 【hookTrigger相关】
+ *
+ * 之后处理方法
+ *
+ * 在createTrigger中最终步骤中,需要当前没有hookTrigger配置才调用到
+ *
+ * 若返回true时,会触发“triggerAfter”
+ *
+ * @param event
+ * @param player
+ * @param triggername
+ */
+ after?(event: GameEventPromise, player: Player, triggername: string): boolean;
+ /**
+ * 【hookTrigger相关】
+ *
+ * 在filterTrigger中执行,过滤发动条件,和filter有些类似,具体功能稍后分析
+ */
+ block?(event: GameEventPromise, player: Player, name: string, skill: string): boolean;
+ /**
+ * 【hookTrigger相关】
+ *
+ * 在logSkill中执行,每次触发logSkill都会触发
+ */
+ log?: ThreeParmFun;
+}
+
+/** mod的配置 */
+declare interface Mod {
+ /**
+ * 卡牌是否可弃置
+ * @param card:Card 牌
+ * @param player:Player 玩家
+ */
+ cardDiscardable?(card: Card, player: Player): boolean | void;
+ /**
+ * 卡牌是否可用(卡牌能否被选择)
+ * cardEnabled一起使用
+ *
+ * 适用范围:player.canUse,lib.filter.cardEnabled,默认lib.filter.filterCard
+ *
+ * @param card:Card 牌
+ * @param player:Player 玩家
+ */
+ cardEnabled?(card: Card, player: Player): boolean | void;
+ /**
+ * 卡牌是否可用(适用范围基本可以视为所有情况下)
+ *
+ * 适用范围:event.backup中技能信息触发(viewAS),cardEnabled(优先于该mod的触发),cardRespondable(优先于该mod的触发),_save(优先于cardSavable的mod触发)中均触发
+ */
+ cardEnabled2?(card: Card, player: Player): boolean | void;
+ /**
+ * 卡牌是否可用(改变卡牌的使用次数)
+ *
+ * 要与cardEnabled一起使用(目前看来两个效果一致)
+ *
+ * @param card Card 牌
+ * @param player Player 玩家
+ * @param num 使用次数
+ */
+ cardUsable?(card: Card, player: Player, num: number): boolean | number | void;
+ /**
+ * 卡牌是否可以响应
+ *
+ * 要与cardEnabled一起使用(目前看来两个效果一致)
+ *
+ * @param card:Card 牌
+ * @param player:Player 玩家
+ */
+ cardRespondable?(card: Card, player: Player): boolean | void;
+ /**
+ * 卡牌是否可以救人
+ *
+ * 要与cardEnabled一起使用(目前看来两个效果一致)
+ *
+ * 注:还是和cardEnabled不同,设置了该mod检测,只要是在_save,濒死求救阶段,都可以触发;
+ *
+ * 不过前提,可能还是要通过该阶段的cardEnabled的检测,目前还没确定,日后再做分析
+ *
+ * 适用范围:濒死阶段的filterCard
+ *
+ * @param card:Card 牌
+ * @param player:Player 玩家
+ * @param taregt:Target 当前处于濒死求救得玩家
+ */
+ cardSavable?(card: Card, player: Player, taregt: Player): boolean | void;
+ /**
+ * 在全局的防御范围
+ *
+ * 注:防御距离就是要和别人的距离越远,所以,拉开距离需要增加;
+ */
+ globalTo?(from: Player, to: Player, current): number | void;
+ /**
+ * 在全局的进攻距离
+ *
+ * 注:进攻距离就是要和别人的距离越近,所以,增加距离需要减掉;
+ */
+ globalFrom?(from: Player, to: Player, distance: number): number | void;
+ /**
+ * 角色的攻击范围
+ * @param from
+ * @param to
+ * @param range
+ *
+ * 注:和globalFrom同理,拉近距离,减去;
+ */
+ attackFrom?(from: Player, to: Player, range: number): number | void;
+ /**
+ * 攻击到角色的范围
+ * @param from
+ * @param to
+ * @param range
+ *
+ * 注:和globalTo同理,拉开距离,增加;
+ */
+ attackTo?(from: Player, to: Player, range: number): number | void;
+ /** 手牌上限 */
+ maxHandcard?(player: Player, num: number): number | void;
+ /**
+ * 选择的目标
+ *
+ * card:牌;
+ *
+ * player:玩家;
+ *
+ * range:
+ * range[1]:目标个数;
+ */
+ selectTarget?(card: Card, player: Player, range: Select): void;
+
+ /**
+ * 该卡牌的发动源玩家是否能使用该卡牌(该角色是否能使用该牌)
+ *
+ * @param card:Card
+ *
+ * @param player:Player 源玩家(使用牌的角色)
+ *
+ * @param target:Target 目标玩家
+ */
+ playerEnabled?(card: Card, player: Player, target: Player): boolean | void;
+ /**
+ * 是否能成为目标
+ *
+ * card:牌;
+ *
+ * player:使用牌的角色;
+ *
+ * target:玩家
+ */
+ targetEnabled?(card: Card, player: Player, target: Player): boolean | void;
+
+ /**
+ * 可以指定任意(范围内)目标
+ *
+ * @param card:Card 牌
+ *
+ * @param player:Player 玩家(使用牌的角色)
+ *
+ * @param target:Target 目标
+ *
+ * @return 返回bool值可以不接受,范围检测,使用返回的结果;返回number,即计算距离是增加该距离;不返回,默认正常的范围检测
+ */
+ targetInRange?(card: Card, player: Player, target: Player): boolean | number | void;
+ /**
+ * 弃牌阶段时,忽略的手牌
+ *
+ * @param card:Card
+ *
+ * @param player:Player
+ */
+ ignoredHandcard?(card: Card, player: Player): boolean | void;
+
+ /** 过滤可以被丢弃的牌 */
+ canBeDiscarded?(card: Card, player: Player, target: Player, eventName: string): boolean | void;
+ /** 过滤可以获得的牌 */
+ canBeGained?(card: Card, player: Player, target: Player, eventName: string): boolean | void;
+
+ /**
+ * 改变花色
+ */
+ suit?(card: Card, suit: string): string | void;
+ /**
+ * 改变判断结果
+ *
+ * 注:目前似乎没有用到该mod.改变结果不影响判定的牌结果,影响判定的最终结果,即之后判定牌的effect会受该结果影响
+ * @param player
+ * @param result
+ */
+ judge?(player: Player, result: JudgeResultData);
+
+ //2020-2-23版本:
+ /**
+ * 为技能配置一个自定义在事件中处理的回调事件,该事件的使用需要自己使用,实际是一个自定义事件,没什么实际意义;
+ *
+ * 其设置的位置在技能content期间设置,设置在期间引发的事件中;
+ *
+ * 用于以下场合:judge,chooseToCompareMultiple,chooseToCompare
+ *
+ * 新版本的judge事件中 可以通过设置callback事件 在judgeEnd和judgeAfter时机之前对判定牌进行操作
+ *
+ * 在判断结果出来后,若事件event.callback存在,则发送“judgeCallback”事件
+ *
+ * 同理拼点,在拼点结果出来后,发送“compareMultiple”事件(“compare”暂时没有)
+ *
+ * callback就是作为以上事件的content使用
+ */
+ callback?: ContentFuncByAll;
+
+ //无懈相关:主要在_wuxie中,(此时应时无懈询问阶段),检测触发卡牌以下对应mod
+ /*
+ 主要参数解析:
+ card:trigger.card 触发该无懈阶段的卡牌;
+
+ player:当前事件的玩家(应该也是触发该阶段的玩家)
+
+ target:trigger.target 触发该无懈阶段的卡牌的玩家;
+
+ current:当前game.filterPlayer,遍历过滤检测可以发动无懈的每一个玩家(即当前过滤检测中的玩家)
+ */
+ //触发阶段为:phaseJudge(判定阶段)
+ /** 是否能在判定阶段使用无懈 */
+ wuxieJudgeEnabled?(card: Card, player: Player, current: Player): boolean | void;
+ /** 是否能在判定阶段响应无懈 */
+ wuxieJudgeRespondable?(card: Card, player: Player, current: Player): boolean | void;
+ //非判定阶段触发
+ /** 是否能使用无懈 */
+ wuxieEnabled?(card: Card, player: Player, target: Player, current: Player): boolean | void;
+ /** 是否能响应无懈 */
+ wuxieRespondable?(card: Card, player: Player, target: Player, current: Player): boolean | void;
+
+ //94版本
+ /** 改变卡牌名字 用于get.name*/
+ cardname?(card: Card, player: Player): string | void;
+ /** 改变卡牌伤害属性 用于get.nature*/
+ cardnature?(card: Card, player: Player): string | void;
+
+ /** 对特定角色使用牌的次数限制(用于优化【对特定角色使用牌无次数限制】的机制)【v1.9.105】 */
+ cardUsableTarget?(card: Card, player: Player, target: Player): boolean | void;
+
+ /** 用于get.value,对最后得返回value结果做处理 */
+ aiValue?(player: Player, card: Card, num: number): number | void;
+ /** 用于get.order,对最后得返回order结果做处理 */
+ aiOrder?(player: Player, card: Card, num: number): number | void;
+
+ //player.inRange新增:
+ /** 在玩家范围内,即target是否在player的攻击范围内 */
+ inRange?(from: Player, to: Player): boolean | void;
+ /** 在目标范围内,即player是否在source的攻击范围内 */
+ inRangeOf?(from: Player, to: Player): boolean | void;
+
+ /**
+ * 强制判断卡牌能否重铸
+ * 【v1.9.108.6~】
+ */
+ cardChongzhuable?(card: Card, player: Player): boolean | void;
+
+ aiValue?(player: Player, card: Card, num: number): number | void;
+ aiUseful?(player: Player, card: Card, num: number): number | void;
+}
+
+/** 技能 */
+declare interface Skill {
+ /**
+ * 技能按钮名字,不写则默认为此技能的翻译(可认为为该技能用于显示的翻译名)
+ * 注:用得挺少得,貌似主要是使用翻译得
+ */
+ name?: string;
+ /**
+ * 新版:用于记录自身名字key,希望能用于自身某些配置上直接使用......,需要测试过才肯定;【结果:失败,还是没用,屏蔽掉】
+ *
+ * 旧版:用于解析用的key,不直接参与游戏逻辑,参与自己定义的解析流程,实质就是技能的名字,规范按技能名命名
+ */
+ // key?:string;
+
+ /**
+ * 继承
+ *
+ * 比较特殊的属性,继承当前技能没有的,而inherit继承技能中有的属性;
+ * 其中“audio”属性,尽可能直接继承赋值为inherit的名字;
+ * 同时,对应的翻译会覆盖成继承技能的翻译。
+ */
+ inherit?: string;
+
+ //声音
+ /**
+ * 配音:
+ *
+ * 主要分为:audioname(默认技能名),audioinfo(默认info.audio)
+ *
+ * 若为字符串时,带有“ext:”,则使用无名杀录目\extension\扩展名内的配音(扩展的配音)
+ *
+ * ,命名方法:技能名+这是第几个配音
+ *
+ *
+ * 否则,该字符串指代的是另一个技能的名字,若该技能名存在,则audioinfo为该技能的audio;
+ *
+ * 若为数组,则是[audioname,audioinfo],分布覆盖原有的值。
+ *
+ * audioinfo为数字时,数字为配音数量索引(同一技能有多个配音),从1开始,使用无名杀目录\audio\skill内的配音(audioname1~audioinfo序号);
+ *
+ * audioinfo为布尔值true或者字符串非空时,执行game.playSkillAudio(audioname),使用无名杀目录\audio\skill内的配音;
+ *
+ * 否则,若为false,空字符串,null结果,则不播音,
+ *
+ * 若info.audio:true,则使用game.playSkillAudio(audioname)。
+ *
+ * 扩展(以game.trySkillAudio为准):
+ *
+ * 若info.audio是字符串:
+ *
+ * 1.则主要是播放扩展声音,格式:ext:扩展包的名字:额外参数;
+ *
+ * 2.直接就是技能名,即继承该技能的播放信息,audioinfo;
+ *
+ * 若info.audio是数组,则[扩展名,额外参数];
+ *
+ * 额外参数:1."true",则直接播放该名字的声音;2.数字,则是随机选一个该"技能名+1-数字范围"的声音播放;
+ *
+ * 若info.audio是数字,则直接就是用解析出来的"audioname+1-数字范围";
+ */
+ audio?: number | string | boolean | [string, number];
+ /**
+ * 指定武将名的音频。
+ *
+ * 强制使用该audioname覆盖上面解析出来的audioname,其解析出来的audioname为“audioname_玩家武将名”,
+ *
+ * 最终路径为:无名杀目录\audio\“audioname_玩家武将名”
+ *
+ * 扩展:
+ * 若info.audioname存在,且是数组,且方法参数有player,则播放"audioname_玩家名"的声音(即可同一个技能,不同人播放不同声音)
+ */
+ audioname?: string[];
+ //【v1.9.102】
+ /**
+ * 添加audioname2机制,用于重定向特定角色的语音到特定技能
+ *
+ * 其key值为人物的name;
+ */
+ audioname2?: SMap;
+ /** 强制播放音频 */
+ forceaudio?: boolean;
+
+
+ //时机与触发相关
+ /**
+ * 触发的时机
+ *
+ * 一般用于触发技能(被动技能)
+ *
+ * 注1:主动触发enable,是没有event._trigger;
+ *
+ * 注2:有trigger,就表示这是一个触发技能,触发技能必须要有触发内容“content”,没有会引发报错;
+ */
+ trigger?: SkillTrigger;
+
+ /**
+ * 为true时,将该技能加入到_hookTrigger
+ *
+ * 根据代码理解:
+ *
+ * 通过addSkillTrigger,挂载在player._hookTrigger中;
+ *
+ * 作为一个单独触发的方式,每次createTrigger,logSkill,filterTriggers时执行所有挂载在_hookTrigger所有对应的hookTrigger;
+ *
+ * 目前可知,其相关使用方法:after,block,log【目前只有于国战方法中,应该是作为全局执行方法的一种简约写法,实用不大】
+ */
+ hookTrigger?: HookTrigger;
+
+ /** 同时机技能发动的优先度 */
+ priority?: number;
+
+ //基本都在核心createTrigger,addTrigger,trigger中逻辑触发相关,属于重要得属性
+ /**
+ * 目前具体不知什么功能,当前所知,非常重要,和createTrigger,addTrigger,trigger相关
+ * (推测,这属性是指明客户端是否显示该技能的操作按钮)
+ *
+ * 1.用于双将,若该设置不为true,该技能时在hiddenSkills隐藏技能列表中,且为“非明置”状态,结束当前“createTrigger”事件的触发;
+ * 即该设置,可以让隐藏技能触发;
+ *
+ * 2.用于event.addTrigger,event.trigger中,若该设置为true,默认为其priority+1,影响技能的触发顺序
+ * (该顺序从代码看起来主要受priority影响,因为会*100,设置这个,会比其他同级优先一点)
+ *
+ * 3.当设置了该值为true,
+ * 若forced没设置到,则默认为true;
+ * 若popup没设置到,则默认为false;
+ *
+ * 故该设置核心功能:表明该技能是强行触发技能,并且不提示
+ */
+ silent?: boolean;
+ /**
+ * 目前具体不清楚什么功能,当前所知,也是个很重要得属性,估计是托管时是否触发得标记
+ *
+ * 功能相当于forced+nopop ,会不会是被托管时的标记呢,正在验证
+ *
+ * 用于双将,上面的silent为true,其非明置,该设置不为true,则触发“triggerHidden”;
+ *
+ * 功能好像是直接触发,在createTrigger中,直接event._result={bool:true}执行,否则可能需要(info.check进行ai检测);
+ */
+ direct?: boolean;
+ /**
+ * 此技能是否可以被设置为自动发动(不询问)
+ *
+ * 设置了该属性的技能,可加入到配置选项中,自己设置是否自动发动(即该技能非必发技能)
+ *
+ * 若该属性值是“check”,则调用当前技能得check方法检测
+ */
+ frequent?: boolean | string | TwoParmFun;
+ /**
+ * 此技能是否可以被设置为自动发动2
+ *
+ * 可以细分当前技能强制发动选项,(应该是为了细分子技能),保存到lib.config.autoskilllist,
+ *
+ * 在ui.click.autoskill2中执行,
+ *
+ * 取值为子技能的名字(注:目前,看来,只是在UI上作用,自动发动,更多是依赖frequent参数)
+ */
+ subfrequent?: string[];
+ /**
+ * 自动延迟的时间
+ *
+ * 可以影响技能触发响应时间(主要影响loop之间的时间,即game.delayx的调用情况)
+ */
+ autodelay?: boolean | number | TwoParmFun;
+ /** 第一时刻执行?(将发动顺序前置到列表前) */
+ firstDo?: boolean;
+ /** 最后一刻做?(将发动顺序置于列表后方) */
+ lastDo?: boolean;
+
+ /**
+ * 此技能是否能固定触发(即自动发动)。
+ *
+ * true为固定触发(可视为一种锁定技的,锁定技实质是mod里的技能)
+ * 国战可以触发亮将。
+ *
+ * 【核心】作为game.check检测用的标准属性之一,在满足条件下强制执行。
+ */
+ forced?: boolean;
+ /**
+ * 死亡后是否可以发动技能
+ */
+ forceDie?: boolean;
+ /**
+ * 是否触发可以弹出选择技能的发动
+ *
+ * 用于在arrangeTrigger过滤出多个同时机的触发技能时,在createTrigger中,询问玩家的技能发动,
+ *
+ * 若为false,不会加入询问触发的技能列表上(只有设置false才会);
+ *
+ * 若为字符串,则在createTrigger【step 3】触发技能时,使用player.popup弹出该提示文本;
+ */
+ popup?: boolean | string;
+ /**
+ * player是否logSkill('此技能').
+ *
+ * 设置true,则不弹出提示
+ *
+ * 注:logSkill 则是在玩家确定要使用卡牌的情况下 弹出发动的技能(马里奥大佬的解释,到时看下)
+ * true为不
+ */
+ nopop?: boolean;
+ /**
+ * 取消触发后的处理
+ *
+ * 在createTrigger中step 3处理
+ *
+ * @param trigger
+ * @param player
+ */
+ oncancel?(trigger: GameEventPromise, player: Player): void;
+
+ //触发内容基本触发流程
+ /**
+ * 在content之前执行
+ *
+ * 在chooseToUse,step2中执行:
+ * 其执行时机和chooseButton一致,当chooseButton不存在时且game.online为false,则会执行这个
+ * @param config
+ */
+ precontent?: ContentFuncByAll;
+ /**
+ * 在content之前触发内容
+ *
+ * 在useSkill中使用,主动触发技能content之前
+ */
+ contentBefore?: ContentFuncByAll;
+ /**
+ * 触发内容(技能内容)
+ *
+ * 作为被动触发技能:
+ * 在createTrigger,step3中创建当前技能的事件,设置该content为事件content作为触发内容;
+ *
+ * 作为主动触发技能:
+ * 在useSkill中创建当前技能的事件
+ * 分步执行(通过step x分割开执行逻辑步骤)
+ *
+ * 注:此时的content,已经为触发该技能的效果而创建的,该技能执行中的事件,此时的event一般是不具备
+ * 触发信息,触发的信息,主要在trigger触发事件中获取。
+ */
+ content?: ContentFuncByAll;
+ /**
+ * 在content之后触发内容
+ *
+ * 在useSkill中使用,主动触发技能content之后
+ */
+ contentAfter?: ContentFuncByAll;
+
+ //技能初始化与移除:
+ /**
+ * 获得技能时发动,初始化技能
+ *
+ * 技能的话,则在addSkillTrigger,若第三个参数triggeronly取值为true,只设置触发,不初始化该技能;
+ *
+ * 正常在addSkill处理,this.addSkillTrigger(skill),使用此初始化;
+ */
+ init?(player: Player, skill: string): void;
+ /**
+ * 添加技能时,初始化技能信息
+ *
+ * 在addSkill中调用,每次添加都会执行
+ */
+ init2?(player: Player, skill: string): void;
+ /** 在执行player.disableSkill丧失技能时,若该属性为true,则执行技能的onremove */
+ ondisable?: boolean;
+ /**
+ * 失去技能时发动
+ * 当值为string时:
+ *
+ * 若为“storage”,删除player.storage中该技能的缓存(用于保存标记等信息);
+ * 注:失去这个技能时销毁标记。
+ *
+ * 若为“discard”,若player.storage[skill]缓存的是卡牌时,执行game.cardsDiscard,并播放丢牌动画,然后移除player.storage[skill];
+ *
+ * 若为“lose”,和“discard”差不多,不过不播丢牌动画;
+ *
+ * 当值为true时,直接移除player.storage[skill];
+ *
+ * 当值为字符串集合时,则是删除集合中对应player.storage(即删除多个指定storage)
+ *
+ * 注:当前disableSkill中,若当前info.ondisable,调用onremove必须是方法,且不注入skill参数;
+ */
+ onremove?: TwoParmFun | string | string[] | boolean;
+ /** 是否持续的附加技能,在removeSkill中使用 */
+ keepSkill?: boolean;
+
+
+ //以下3个属性基本功能时一致:在某些模式下是否能使用,只使用一个就差不多
+ /**
+ * 指定该技能在哪些模式下禁用
+ *
+ * 注:在指定模式被禁用的技能,会被设置成空对象,并且“技能_info”的描述变成“此模式下不可用”。
+ */
+ forbid?: string[];
+ /** 与forbid相反,只能在指定玩法模式下才能被使用,其他逻辑一致 */
+ mode?: string[];
+ /** 当前模式下是否能使用,返回false则不能使用,其实和forbid逻辑一致 */
+ available?(mode: string): boolean;
+
+
+ //技能相关设置:
+ /**
+ * 技能组:
+ *
+ * 拥有这个技能时相当于拥有技能组内的技能
+ *
+ * 注:一些特殊技能标签:
+ *
+ * “undist”:不计入距离的计算且不能使用牌且不是牌的合法目标
+ *
+ * (被隔离玩家,目前确定的作用:player.getNext获取下一位玩家,player.getPrevious确定上一位玩家,player.distance计算玩家距离);
+ */
+ group?: string | string[];
+ /**
+ * 子技能:
+ *
+ * 你不会拥有写在这里面的技能,可以调用,可以用技能组联系起来;
+ *
+ * 子技能名字:“主技能_子技能”,翻译为主技能翻译
+ *
+ * 注:子技能,会被视为“技能_子技能”独立保存起来。
+ */
+ subSkill?: SMap;
+ /**
+ * 全局技能?:
+ *
+ * 你拥有此技能时,所有角色拥有此技能(global的值为技能名)
+ *
+ * 注:无论是否拥有此技能,此技能都为全局技能写法:技能名前 + _
+ */
+ global?: string | string[];
+ /**
+ * 在game.addGlobalSkill中使用:
+ *
+ * 强行设置global技能;
+ */
+ globalSilent?: boolean;
+
+ //技能相关设置=>功能设置
+ /**
+ * 每回合限制使用次数
+ *
+ * (若限制使用次数为变量时需写在filter内,即通过filter与变量动态判断)
+ *
+ * 主要在createTrigger,step3中触发计数。
+ *
+ * 触发计数,会在玩家身上添加“counttrigger”技能,计数记录在:player.storage.counttrigger[当前技能名]
+ */
+ usable?: number;
+ /**
+ * 每一轮的使用次数
+ *
+ * 设置了该属性,会创建一个“技能名_roundcount”技能,将其加入group(技能组)中;
+ *
+ * 该技能的触发阶段“roundStart”(一轮的开始),用于记录当前技能的在一轮中使用的次数
+ */
+ round?: number;
+ /** 用于“技能名_roundcount”技能中,当前技能不可使用时,“n轮后”xxx,中xxx的部分显示(即后面部分) */
+ roundtext?: string;
+ /** 增加显示的信息,这部分时增加,“n轮后”前面部分 */
+ addintro?(storage: SMap, player: Player): string;
+ /** 延迟的时间 */
+ delay?: number;
+ /**
+ * 锁定技
+ *
+ * 若取值false,则get.is.locked,直接返回就false了;
+ *
+ * (锁定技的判定:1.info.trigger&&info.forced;2.info.mod;3.info.locked)
+ *
+ * 是否可以被“封印”(内置技能“fengyin”)的技能,取值为false时,get.is.locked返回为false;true则正常逻辑
+ */
+ locked?: boolean;
+ /** 是否是旧版技能,值为true,添加到lib.config.vintageSkills中,可以实现新/旧版技能切换,如果该为true,则“原翻译名_alter”即作为当前的翻译 */
+ alter?: boolean;
+
+
+ //锁定技
+ /**
+ * mod技能的设置
+ *
+ * 如果有,技能视为锁定技
+ * */
+ mod?: Mod;
+
+ //【重点】标记的key需要和技能名一致,游戏内都是通过对应skill取得对应的标记key,即player.storage[skill]
+ //限定技与觉醒技与技能标记
+ /*
+ 关于限定技规范:
+ 一般情况下,需要在filter中,可加入!player.storage.xxx==true判定,
+ 在发动后,content内设置player.storage.xxx=true,代表已经触发了;
+ 目前,可以采用另一种简洁的方法,即觉醒技方法:
+ player.awakenSkill("xxx");
+ 这样就会屏蔽发动过的技能,不会发动第二次;
+ */
+
+ /**
+ * 限定技(标记)
+ *
+ * 该标记为true时,若没有设置以下内容,则会自动设置:
+ *
+ * mark设置为true;
+ *
+ * intro.content设置为“limited”;
+ *
+ * skillAnimation设置为true;
+ *
+ * init设置为初始化玩家缓存的该技能名标记为false;
+ */
+ limited?: boolean;
+ /**
+ * 是否开启觉醒动画
+ *
+ * 准备来说,常用于觉醒动画,实际是指技能动画
+ *
+ * 字符串时取值:epic,legend
+ */
+ skillAnimation?: boolean | string;
+ /** 是否只显示文字特效 */
+ textAnimation?: boolean;
+ /** 动画文字(可用于觉醒文字) */
+ animationStr?: string;
+ /** 动画文字颜色(觉醒文字颜色) */
+ animationColor?: string;
+ /**
+ * 觉醒技标记:
+ *
+ * (目前来看,这个目前单纯是技能标记,在主逻辑上并没使用,但貌似会被某些技能本身用到,或者类似左慈判断不能获得的技能的)
+ */
+ juexingji?: boolean;
+ /**
+ * 获得技能时是否显示此标记,
+ *
+ * 若为false,可以用 markSkill 来显示此标记,
+ *
+ * 可以用 unmarkSkill 不显示标记
+ *
+ * mark的常量值:"card","cards","image","character",表示,标记显示的特殊形式(UI上)
+ *
+ * 注:character,只能在表示一个角色时使用,标记以角色牌形式显示;
+ *
+ * 注:取值“auto”,在updateMark时,有计数时,执行unmarkSkill(?????)
+ */
+ mark?: boolean | string;
+ /** 标记显示文本,一般为一个字 */
+ marktext?: string;
+ /** 标记显示内容 */
+ intro?: {
+ /** 自定义mark弹窗的显示内容 */
+ mark?: ThreeParmFun