diff --git a/audio/die/clan_wanghun.mp3 b/audio/die/clan_wanghun.mp3 new file mode 100644 index 0000000000..e740c6428e Binary files /dev/null and b/audio/die/clan_wanghun.mp3 differ diff --git a/audio/die/clan_wukuang.mp3 b/audio/die/clan_wukuang.mp3 new file mode 100644 index 0000000000..3a3bbb4d1b Binary files /dev/null and b/audio/die/clan_wukuang.mp3 differ diff --git a/audio/die/clan_zhongyan.mp3 b/audio/die/clan_zhongyan.mp3 new file mode 100644 index 0000000000..d32ad7e96e Binary files /dev/null and b/audio/die/clan_zhongyan.mp3 differ diff --git a/audio/die/dongxie.mp3 b/audio/die/dongxie.mp3 new file mode 100644 index 0000000000..eb8c5502f6 Binary files /dev/null and b/audio/die/dongxie.mp3 differ diff --git a/audio/die/duanjiong.mp3 b/audio/die/duanjiong.mp3 new file mode 100644 index 0000000000..59738fd6da Binary files /dev/null and b/audio/die/duanjiong.mp3 differ diff --git a/audio/die/ol_wenqin.mp3 b/audio/die/ol_wenqin.mp3 new file mode 100644 index 0000000000..bdd0a1bc73 Binary files /dev/null and b/audio/die/ol_wenqin.mp3 differ diff --git a/audio/die/peiyuanshao.mp3 b/audio/die/peiyuanshao.mp3 new file mode 100644 index 0000000000..8268990d59 Binary files /dev/null and b/audio/die/peiyuanshao.mp3 differ diff --git a/audio/die/sb_zhanghe.mp3 b/audio/die/sb_zhanghe.mp3 new file mode 100644 index 0000000000..38862e4302 Binary files /dev/null and b/audio/die/sb_zhanghe.mp3 differ diff --git a/audio/die/xin_guozhao.mp3 b/audio/die/xin_guozhao.mp3 new file mode 100644 index 0000000000..172c3c5cff Binary files /dev/null and b/audio/die/xin_guozhao.mp3 differ diff --git a/audio/die/xin_zhangyi.mp3 b/audio/die/xin_zhangyi.mp3 new file mode 100644 index 0000000000..2732e02dcd Binary files /dev/null and b/audio/die/xin_zhangyi.mp3 differ diff --git a/audio/skill/chuhai3.mp3 b/audio/skill/chuhai3.mp3 new file mode 100644 index 0000000000..38de0e1398 Binary files /dev/null and b/audio/skill/chuhai3.mp3 differ diff --git a/audio/skill/clanbaozu_clan_zhongyan1.mp3 b/audio/skill/clanbaozu_clan_zhongyan1.mp3 new file mode 100644 index 0000000000..770c9cf5be Binary files /dev/null and b/audio/skill/clanbaozu_clan_zhongyan1.mp3 differ diff --git a/audio/skill/clanbaozu_clan_zhongyan2.mp3 b/audio/skill/clanbaozu_clan_zhongyan2.mp3 new file mode 100644 index 0000000000..1976213156 Binary files /dev/null and b/audio/skill/clanbaozu_clan_zhongyan2.mp3 differ diff --git a/audio/skill/clanchenya1.mp3 b/audio/skill/clanchenya1.mp3 new file mode 100644 index 0000000000..7e5d95e697 Binary files /dev/null and b/audio/skill/clanchenya1.mp3 differ diff --git a/audio/skill/clanchenya2.mp3 b/audio/skill/clanchenya2.mp3 new file mode 100644 index 0000000000..7cd14cfce3 Binary files /dev/null and b/audio/skill/clanchenya2.mp3 differ diff --git a/audio/skill/clanfuxun1.mp3 b/audio/skill/clanfuxun1.mp3 new file mode 100644 index 0000000000..1bd834c432 Binary files /dev/null and b/audio/skill/clanfuxun1.mp3 differ diff --git a/audio/skill/clanfuxun2.mp3 b/audio/skill/clanfuxun2.mp3 new file mode 100644 index 0000000000..587d2678f1 Binary files /dev/null and b/audio/skill/clanfuxun2.mp3 differ diff --git a/audio/skill/clanguangu1.mp3 b/audio/skill/clanguangu1.mp3 new file mode 100644 index 0000000000..ffceae1db4 Binary files /dev/null and b/audio/skill/clanguangu1.mp3 differ diff --git a/audio/skill/clanguangu2.mp3 b/audio/skill/clanguangu2.mp3 new file mode 100644 index 0000000000..11d6e3d0d2 Binary files /dev/null and b/audio/skill/clanguangu2.mp3 differ diff --git a/audio/skill/clanlianzhu1.mp3 b/audio/skill/clanlianzhu1.mp3 new file mode 100644 index 0000000000..73b6421376 Binary files /dev/null and b/audio/skill/clanlianzhu1.mp3 differ diff --git a/audio/skill/clanlianzhu2.mp3 b/audio/skill/clanlianzhu2.mp3 new file mode 100644 index 0000000000..d84b025603 Binary files /dev/null and b/audio/skill/clanlianzhu2.mp3 differ diff --git a/audio/skill/clanmuyin_clan_wukuang1.mp3 b/audio/skill/clanmuyin_clan_wukuang1.mp3 new file mode 100644 index 0000000000..3e15f3246e Binary files /dev/null and b/audio/skill/clanmuyin_clan_wukuang1.mp3 differ diff --git a/audio/skill/clanmuyin_clan_wukuang2.mp3 b/audio/skill/clanmuyin_clan_wukuang2.mp3 new file mode 100644 index 0000000000..57974fc382 Binary files /dev/null and b/audio/skill/clanmuyin_clan_wukuang2.mp3 differ diff --git a/audio/skill/clanxiaoyong1.mp3 b/audio/skill/clanxiaoyong1.mp3 new file mode 100644 index 0000000000..2692a86523 Binary files /dev/null and b/audio/skill/clanxiaoyong1.mp3 differ diff --git a/audio/skill/clanxiaoyong2.mp3 b/audio/skill/clanxiaoyong2.mp3 new file mode 100644 index 0000000000..81ed8ede90 Binary files /dev/null and b/audio/skill/clanxiaoyong2.mp3 differ diff --git a/audio/skill/clanzhongliu_clan_wanghun1.mp3 b/audio/skill/clanzhongliu_clan_wanghun1.mp3 new file mode 100644 index 0000000000..53f920c820 Binary files /dev/null and b/audio/skill/clanzhongliu_clan_wanghun1.mp3 differ diff --git a/audio/skill/clanzhongliu_clan_wanghun2.mp3 b/audio/skill/clanzhongliu_clan_wanghun2.mp3 new file mode 100644 index 0000000000..720e9c7a33 Binary files /dev/null and b/audio/skill/clanzhongliu_clan_wanghun2.mp3 differ diff --git a/audio/skill/dchumei1.mp3 b/audio/skill/dchumei1.mp3 new file mode 100644 index 0000000000..9a6e40f044 Binary files /dev/null and b/audio/skill/dchumei1.mp3 differ diff --git a/audio/skill/dchumei2.mp3 b/audio/skill/dchumei2.mp3 new file mode 100644 index 0000000000..47dc6de1eb Binary files /dev/null and b/audio/skill/dchumei2.mp3 differ diff --git a/audio/skill/dcjiaoxia1.mp3 b/audio/skill/dcjiaoxia1.mp3 new file mode 100644 index 0000000000..9eb9ed12fc Binary files /dev/null and b/audio/skill/dcjiaoxia1.mp3 differ diff --git a/audio/skill/dcjiaoxia2.mp3 b/audio/skill/dcjiaoxia2.mp3 new file mode 100644 index 0000000000..5b3e56669f Binary files /dev/null and b/audio/skill/dcjiaoxia2.mp3 differ diff --git a/audio/skill/dcmoyu1.mp3 b/audio/skill/dcmoyu1.mp3 new file mode 100644 index 0000000000..798caa6054 Binary files /dev/null and b/audio/skill/dcmoyu1.mp3 differ diff --git a/audio/skill/dcmoyu2.mp3 b/audio/skill/dcmoyu2.mp3 new file mode 100644 index 0000000000..a9b7567a38 Binary files /dev/null and b/audio/skill/dcmoyu2.mp3 differ diff --git a/audio/skill/olguangao1.mp3 b/audio/skill/olguangao1.mp3 new file mode 100644 index 0000000000..d4354bf3d8 Binary files /dev/null and b/audio/skill/olguangao1.mp3 differ diff --git a/audio/skill/olguangao2.mp3 b/audio/skill/olguangao2.mp3 new file mode 100644 index 0000000000..b477639a03 Binary files /dev/null and b/audio/skill/olguangao2.mp3 differ diff --git a/audio/skill/olhuiqi1.mp3 b/audio/skill/olhuiqi1.mp3 new file mode 100644 index 0000000000..d9f84c4fc3 Binary files /dev/null and b/audio/skill/olhuiqi1.mp3 differ diff --git a/audio/skill/olhuiqi2.mp3 b/audio/skill/olhuiqi2.mp3 new file mode 100644 index 0000000000..2d68a6ae1e Binary files /dev/null and b/audio/skill/olhuiqi2.mp3 differ diff --git a/audio/skill/olsaogu1.mp3 b/audio/skill/olsaogu1.mp3 new file mode 100644 index 0000000000..75b4086b95 Binary files /dev/null and b/audio/skill/olsaogu1.mp3 differ diff --git a/audio/skill/olsaogu2.mp3 b/audio/skill/olsaogu2.mp3 new file mode 100644 index 0000000000..f826c1a3ac Binary files /dev/null and b/audio/skill/olsaogu2.mp3 differ diff --git a/audio/skill/olxieju1.mp3 b/audio/skill/olxieju1.mp3 new file mode 100644 index 0000000000..9655e514ab Binary files /dev/null and b/audio/skill/olxieju1.mp3 differ diff --git a/audio/skill/olxieju2.mp3 b/audio/skill/olxieju2.mp3 new file mode 100644 index 0000000000..11758552f9 Binary files /dev/null and b/audio/skill/olxieju2.mp3 differ diff --git a/audio/skill/sbqiaobian1.mp3 b/audio/skill/sbqiaobian1.mp3 new file mode 100644 index 0000000000..d88f2b345d Binary files /dev/null and b/audio/skill/sbqiaobian1.mp3 differ diff --git a/audio/skill/sbqiaobian2.mp3 b/audio/skill/sbqiaobian2.mp3 new file mode 100644 index 0000000000..6d2afdf53f Binary files /dev/null and b/audio/skill/sbqiaobian2.mp3 differ diff --git a/audio/skill/wufei1.mp3 b/audio/skill/wufei1.mp3 new file mode 100644 index 0000000000..f2537775e1 Binary files /dev/null and b/audio/skill/wufei1.mp3 differ diff --git a/audio/skill/wufei2.mp3 b/audio/skill/wufei2.mp3 new file mode 100644 index 0000000000..9439f7e5e3 Binary files /dev/null and b/audio/skill/wufei2.mp3 differ diff --git a/audio/skill/xinwurong1.mp3 b/audio/skill/xinwurong1.mp3 new file mode 100644 index 0000000000..61e971b610 Binary files /dev/null and b/audio/skill/xinwurong1.mp3 differ diff --git a/audio/skill/xinwurong2.mp3 b/audio/skill/xinwurong2.mp3 new file mode 100644 index 0000000000..b87e7e5ed6 Binary files /dev/null and b/audio/skill/xinwurong2.mp3 differ diff --git a/audio/skill/xinwurong3.mp3 b/audio/skill/xinwurong3.mp3 new file mode 100644 index 0000000000..4f4fc8d0da Binary files /dev/null and b/audio/skill/xinwurong3.mp3 differ diff --git a/audio/skill/yichong1.mp3 b/audio/skill/yichong1.mp3 new file mode 100644 index 0000000000..264f899d53 Binary files /dev/null and b/audio/skill/yichong1.mp3 differ diff --git a/audio/skill/yichong2.mp3 b/audio/skill/yichong2.mp3 new file mode 100644 index 0000000000..39845dc5a7 Binary files /dev/null and b/audio/skill/yichong2.mp3 differ diff --git a/card/extra.js b/card/extra.js index 12f570962b..d7178ff786 100644 --- a/card/extra.js +++ b/card/extra.js @@ -281,7 +281,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ content:function(){ target.link(); }, - chongzhu:true, + recastable:true, ai:{ wuxie:function(target,card,player,viewer){ if(_status.event.getRand()<0.5) return 0; diff --git a/card/guozhan.js b/card/guozhan.js index 177477d4c0..9c848a017b 100644 --- a/card/guozhan.js +++ b/card/guozhan.js @@ -397,7 +397,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ player.logSkill('taipingyaoshu'); player.draw(2); 'step 1' - if(player.hp>1) player.loseHp(); + if(player.hp>1||get.mode()=='guozhan') player.loseHp(); } }, yuxi:{ @@ -455,28 +455,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ return target!=player&&(get.mode()!='guozhan'||_status.mode=='yingbian'||_status.mode=='free'||target.countCards('e')>0); }, enable:true, - yingbian_prompt:function(card){ - var str=''; - if(get.cardtag(card,'yingbian_all')){ - str+='此牌的效果改为依次执行所有选项'; - } - if(!str.length||get.cardtag(card,'yingbian_add')){ - if(str.length) str+=';'; - str+='当你使用此牌选择目标后,你可为此牌增加一个目标'; - } - return str; - }, - yingbian:function(event){ - var card=event.card,bool=false; - if(get.cardtag(card,'yingbian_all')){ - bool=true; - card.yingbian_all=true; - game.log(card,'执行所有选项'); - } - if(!bool||get.cardtag(card,'yingbian_add')){ - event.yingbian_addTarget=true; - } - }, + defaultYingbianEffect:'add', content:function(){ 'step 0' if(event.card.yingbian_all){ @@ -577,7 +556,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, mode:['guozhan','versus'], filterTarget:true, - chongzhu:true, + recastable:true, changeTarget:function(player,targets){ var target=targets[0]; game.filterPlayer(function(current){ @@ -942,7 +921,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ fullskin:true, type:'trick', enable:true, - chongzhu:true, + recastable:true, filterTarget:function(card,player,target){ if(player==target) return false; return (target.countCards('h')||target.isUnseen(2)); @@ -1496,7 +1475,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ return current.isFriendOf(player); }); } - return num+game.countGroup(); + return num+game.countGroup()-1; } }, trigger:{player:'damageBegin4'}, @@ -1687,34 +1666,23 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, g_diaohulishan:{}, diaohulishan:{ - trigger:{player:['damageBegin3','loseHpBefore','recoverBefore']}, - forced:true, - popup:false, - content:function(){ - trigger.cancel(); - }, - mod:{ - cardEnabled:function(){ - return false; - }, - cardSavable:function(){ - return false; - }, - targetEnabled:function(){ - return false; - }, - }, - mark:true, - intro:{ - content:'不计入距离的计算且不能使用牌且不是牌的合法目标且不能失去/回复体力和受到伤害' - }, + charlotte:true, group:'undist', - ai:{ - effect:{ - target:function (card,player,target){ - if(get.tag(card,'recover')||get.tag(card,'damage')) return 'zeroplayertarget'; - }, - }, + init:function(player){ + if(player.isIn()){ + game.broadcastAll(function(player){ + player.classList.add('out'); + },player); + game.log(player,'移出了游戏'); + } + }, + onremove:function(player){ + if(player.isOut()){ + game.broadcastAll(function(player){ + player.classList.remove('out'); + },player); + game.log(player,'移回了游戏'); + } }, }, huxinjing:{ @@ -1815,8 +1783,8 @@ game.import('card',function(lib,game,ui,get,ai,_status){ feilongduofeng3:'飞龙夺凤', feilongduofeng_info:'①当你使用【杀】指定目标后,你可令目标角色弃置一张牌。②当你因使用【杀】而令其他角色进入濒死状态时,你可以获得其一张手牌。', taipingyaoshu:'太平要术', - taipingyaoshu_info:'锁定技。①当你即将收到属性伤害时,取消之。②你的手牌上限+X(X为势力数)。③当你失去装备区里的【太平要术】时,你摸两张牌,然后若你的体力值大于1,你失去1点体力。', - taipingyaoshu_info_guozhan:'锁定技。①当你即将收到属性伤害时,取消之。②你的手牌上限+X(X为与你势力相同的角色数)。③当你失去装备区里的【太平要术】时,你摸两张牌,然后若你的体力值大于1,你失去1点体力。', + taipingyaoshu_info:'锁定技。①当你即将受到属性伤害时,取消之。②你的手牌上限+X(X为场上势力数-1)。③当你失去装备区里的【太平要术】时,你摸两张牌,然后若你的体力值大于1,你失去1点体力。', + taipingyaoshu_info_guozhan:'锁定技。①当你即将受到属性伤害时,取消之。②你的手牌上限+X(X为与你势力相同的角色数)。③当你失去装备区里的【太平要术】时,你摸两张牌,然后你失去1点体力。', yuxi_skill:'玉玺', yuxi_skill2:'玉玺', yuxi:'玉玺', @@ -1836,7 +1804,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ chiling:'敕令', chiling_info:'①出牌阶段,对所有没有势力的角色使用。目标角色选择一项:1、明置一张武将牌,然后摸一张牌;2、弃置一张装备牌;3、失去1点体力。②当【敕令】因判定或弃置而置入弃牌堆时,系统将之移出游戏并将【诏书】置于牌堆底,然后系统于当前回合结束后视为对所有没有势力的角色使用【敕令】。', diaohulishan:'调虎离山', - diaohulishan_info:'出牌阶段,对至多两名其他角色使用。目标角色于此回合结束之前不计入距离的计算且不能使用牌且不是牌的合法目标且不能失去或回复体力或受到伤害。', + diaohulishan_info:'出牌阶段,对至多两名其他角色使用。目标角色于此回合视为移出游戏。', huoshaolianying:'火烧连营', huoshaolianying_bg:'烧', huoshaolianying_info_guozhan:'出牌阶段,对你的下家及其队列中的所有角色使用。你对目标角色造成1点火属性伤害。', diff --git a/card/hearth.js b/card/hearth.js index a754f5e615..9ed1320c90 100644 --- a/card/hearth.js +++ b/card/hearth.js @@ -447,7 +447,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ fullskin:true, type:'trick', enable:true, - // chongzhu:true, + // recastable:true, filterTarget:function(card,player,target){ return target==player; }, diff --git a/card/mtg.js b/card/mtg.js index 03aa6b3086..96c4f01a04 100644 --- a/card/mtg.js +++ b/card/mtg.js @@ -501,7 +501,6 @@ game.import('card',function(lib,game,ui,get,ai,_status){ } if(cardsToGain.length) player.gain(cardsToGain,'draw'); if(cards.length-cardsToGain.length) player.draw(cards.length-cardsToGain.length).log=false; - return cardsToGain; }); }, ai:{ diff --git a/card/sp.js b/card/sp.js index 7aa5a6957d..fc62bb820a 100644 --- a/card/sp.js +++ b/card/sp.js @@ -259,7 +259,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ enable:function(){ return game.countPlayer()>2; }, - chongzhu:function(){ + recastable:function(){ return game.countPlayer()<=2; }, singleCard:true, diff --git a/card/standard.js b/card/standard.js index e18416e8e1..5dd0621441 100644 --- a/card/standard.js +++ b/card/standard.js @@ -100,39 +100,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ if(lib.linked.contains(card.nature)) return '出牌阶段,对你攻击范围内的一名角色使用。其须使用一张【闪】,否则你对其造成1点'+get.translation(card.nature)+'属性伤害。'; return '出牌阶段,对你攻击范围内的一名角色使用。其须使用一张【闪】,否则你对其造成1点伤害。'; }, - yingbian_prompt:function(card){ - var str=''; - if(get.cardtag(card,'yingbian_hit')){ - str+='此牌不可被响应'; - } - if(get.cardtag(card,'yingbian_damage')){ - if(str.length) str+=';'; - str+='此牌的伤害值基数+1'; - } - if(!str.length||get.cardtag(card,'yingbian_add')){ - if(str.length) str+=';'; - str+='当你使用此牌选择目标后,你可为此牌增加一个目标'; - } - return str; - }, - yingbian:function(event){ - var card=event.card,bool=false; - if(get.cardtag(card,'yingbian_hit')){ - bool=true; - event.directHit.addArray(game.players); - game.log(card,'不可被响应'); - } - if(get.cardtag(card,'yingbian_damage')){ - bool=true; - if(typeof event.baseDamage!='number') event.baseDamage=1; - event.baseDamage++; - game.log(event.card,'的伤害值基数+1'); - } - if(!bool||get.cardtag(card,'yingbian_add')){ - event.yingbian_addTarget=true; - } - }, - yingbian_tags:['hit','damage','add'], + defaultYingbianEffect:'add', filterTarget:function(card,player,target){return player!=target}, content:function(){ "step 0" @@ -387,27 +355,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ cardcolor:'red', notarget:true, nodelay:true, - yingbian_prompt:function(card){ - var str=''; - if(get.cardtag(card,'yingbian_gain')){ - str+='当你声明使用此牌时,你获得此牌响应的目标牌'; - } - if(!str.length||get.cardtag(card,'yingbian_draw')){ - if(str.length) str+=';'; - str+='当你声明使用此牌时,你摸一张牌'; - } - return str; - }, - yingbian_tags:['gain','draw'], - yingbian:function(event){ - var bool=false; - if(get.cardtag(event.card,'yingbian_gain')){ - bool=true; - var cardx=event.respondTo; - if(cardx&&cardx[1]&&cardx[1].cards&&cardx[1].cards.filterInD('od').length) event.player.gain(cardx[1].cards.filterInD('od'),'gain2','log'); - } - if(!bool||get.cardtag(event.card,'yingbian_draw')) event.player.draw(); - }, + defaultYingbianEffect:'draw', content:function(){ event.result='shaned'; event.getParent().delayx=false; @@ -889,11 +837,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ selectTarget:-1, cardcolor:'red', reverseOrder:true, - yingbian_prompt:'当你使用此牌选择目标后,你可为此牌减少一个目标', - yingbian_tags:['remove'], - yingbian:function(event){ - event.yingbian_removeTarget=true; - }, + defaultYingbianEffect:'remove', filterTarget:function(card,player,target){ //return target.hp0; }, - yingbian_tags:['all','hit','add'], - yingbian_prompt:function(card){ - var str=''; - if(get.cardtag(card,'yingbian_all')){ - str+='此牌的效果改为依次执行所有选项'; - } - if(get.cardtag(card,'yingbian_hit')){ - if(str.length) str+=';'; - str+='此牌不可被响应'; - } - if(!str.length||get.cardtag(card,'yingbian_add')){ - if(str.length) str+=';'; - str+='当你使用此牌选择目标后,你可为此牌增加一个目标'; - } - return str; - }, - yingbian:function(event){ - var card=event.card,bool=false; - if(get.cardtag(card,'yingbian_all')){ - bool=true; - card.yingbian_all=true; - game.log(card,'执行所有选项'); - } - if(get.cardtag(card,'yingbian_hit')){ - bool=true; - event.directHit.addArray(game.players); - game.log(card,'不可被响应'); - } - if(!bool||get.cardtag(card,'yingbian_add')){ - event.yingbian_addTarget=true; - } - }, + defaultYingbianEffect:'add', content:function(){ var dist=get.distance(player,target); if(dist>1||card.yingbian_all) player.discardPlayerCard(target,'hej',true); @@ -174,11 +143,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ filterTarget:function(card,player,target){ return target!=player&&target.countCards('h')>0; }, - yingbian_prompt:'当你使用此牌选择目标后,你可为此牌增加一个目标', - yingbian_tags:['add'], - yingbian:function(event){ - event.yingbian_addTarget=true; - }, + defaultYingbianEffect:'add', content:function(){ 'step 0' if(player.isDead()||!target.countCards('h')){ @@ -274,30 +239,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ type:'equip', subtype:'equip5', loseDelay:false, - onEquip:function(){ - if(player.countCards('he',function(cardx){ - return cardx!=card; - })>0){ - player.logSkill('tianjitu_skill'); - player.chooseToDiscard(true,function(card){ - return card!=_status.event.card; - },'he').set('card',card); - } - }, - onLose:function(){ - var next=game.createEvent('tianjitu_lose'); - event.next.remove(next); - var evt=event.getParent(); - if(evt.getlx===false) evt=evt.getParent(); - evt.after.push(next); - next.player=player; - next.setContent(function(){ - if(player.countCards('h')<5){ - player.logSkill('tianjitu_skill'); - player.drawTo(5); - } - }); - }, + global:'tianjitu_skill', ai:{ value:function(card,player){ if(player.countCards('h')>3||get.position(card)!='e') return 0.5; @@ -422,23 +364,24 @@ game.import('card',function(lib,game,ui,get,ai,_status){ global:'heiguangkai_ai', }, tongque_skill:{ - trigger:{player:'useCard1'}, + trigger:{player:'yingbian'}, equipSkill:true, forced:true, - filter:function(event,player){ - return !event.card.yingbian&&get.is.yingbian(event.card)&&player.getHistory('useCard',function(evt){ - return get.is.yingbian(evt.card) - }).indexOf(event)==0; - }, - content:function(){ - trigger.card.yingbian=true; - var info=get.info(trigger.card); - if(info&&info.yingbian) info.yingbian(trigger); - player.addTempSkill('yingbian_changeTarget'); - }, + filter:(event,player)=>get.is.yingbianConditional(event.card)&&player.getHistory('useCard',evt=>get.is.yingbianConditional(evt.card)).length<2, + content:()=>{ + trigger.forceYingbian=true; + } }, tianjitu_skill:{ audio:true, + trigger:{player:['equipBegin','loseBegin']}, + forced:true, + equipSkill:true, + filter:(event,player,name)=>name=='equipBegin'?event.card.name=='tianjitu'&&player.hasCard(card=>card!=event.card):event.cards.some(value=>get.position(value)=='e'&&value.name=='tianjitu')&&player.countCards('h')<5, + content:()=>{ + if(event.triggername=='loseBegin') player.drawTo(5); + else player.chooseToDiscard(true,card=>card!=_status.event.getTrigger().card,'he'); + } }, taigongyinfu_skill:{ equipSkill:true, @@ -456,10 +399,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ 'step 1' if(result.bool){ player.logSkill('taigongyinfu_skill'); - player.lose(result.cards,ui.discardPile,'visible'); - player.$throw(result.cards,1000); - game.log(player,'将',result.cards,'置入了弃牌堆'); - player.draw(); + player.recast(result.cards); } }, }, @@ -494,202 +434,69 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, }, _yingbian:{ - trigger:{player:'useCard1'}, + trigger:{player:'yingbian'}, forced:true, popup:false, - firstDo:true, ruleSkill:true, forceLoad:true, - filter:function(event,player){ + filter:(event,player)=>{ if(event.card.yingbian) return false; - var bool=player.hasSkillTag('forceYingbian'); - var card=event.card; - if(get.cardtag(card,'yingbian_kongchao')&&(!player.countCards('h')||bool)) return true; - if(get.cardtag(card,'yingbian_canqu')&&(player.hp==1||bool)) return true; - if(get.cardtag(card,'yingbian_fujia')&&(player.isMaxHandcard()||bool)) return true; - if(get.cardtag(card,'yingbian_zhuzhan')) return true; - return false; + const temporaryYingbian=event.temporaryYingbian||[],card=event.card; + if(temporaryYingbian.includes('force')||get.cardtag(card,'yingbian_force')) return true; + const forceYingbian=event.forceYingbian||player.hasSkillTag('forceYingbian'); + for(const entry of lib.yingbian.condition.simple){ + const key=entry[0]; + if((temporaryYingbian.includes(key)||get.cardtag(card,`yingbian_${key}`))&&(forceYingbian||entry[1](event))) return true; + } + const complexYingbianConditions=get.complexYingbianConditions(); + return temporaryYingbian.some(value=>complexYingbianConditions.includes(value))||get.is.complexlyYingbianConditional(card); }, - content:function(){ + content:()=>{ 'step 0' - var card=trigger.card; - event.card=card; - var bool=false; - if(get.cardtag(card,'yingbian_kongchao')&&!player.countCards('h')){ - player.popup('空巢','soil'); - bool=true; - } - else if(get.cardtag(card,'yingbian_canqu')&&player.hp==1){ - player.popup('残躯','fire'); - bool=true; - } - else if(get.cardtag(card,'yingbian_fujia')&&player.isMaxHandcard()){ - player.popup('富甲','orange'); - bool=true; - } - else if(player.hasSkillTag('forceYingbian')){ - player.popup('应变','metal'); - bool=true; + event.card=trigger.card; + event.temporaryYingbian=trigger.temporaryYingbian||[]; + var yingbianConditionSatisfied=false; + lib.yingbian.condition.simple.forEach((value,key)=>{ + if(!event.temporaryYingbian.includes(key)&&!get.cardtag(event.card,`yingbian_${key}`)||!value(trigger)) return; + player.popup(`yingbian_${key}_tag`,lib.yingbian.condition.color.get(key)); + if(!yingbianConditionSatisfied) yingbianConditionSatisfied=true; + }); + if(event.temporaryYingbian.includes('force')||get.cardtag(event.card,'yingbian_force')||trigger.forceYingbian||player.hasSkillTag('forceYingbian')){ + player.popup('yingbian_force_tag',lib.yingbian.condition.color.get('force')); + if(!yingbianConditionSatisfied) yingbianConditionSatisfied=true; } - if(bool){ - game.log(player,'触发了',card,'的应变条件'); - event.goto(10); + if(yingbianConditionSatisfied){ + game.log(player,'触发了',event.card,'的应变条件'); + event.goto(4); } + else if((event.num=0)>=(event.yingbianConditions=get.complexYingbianConditions()).length) event.finish(); 'step 1' - event._global_waiting=true; - event.send=function(player,card,source,targets,id,id2,skillState){ - if(skillState){ - player.applySkills(skillState); - } - var type=get.type2(card); - var str=get.translation(source); - if(targets&&targets.length){ - str+='对'; - str+=get.translation(targets); - } - str+='使用了'; - var next=player.chooseCard({ - filterCard:function(card){ - return get.type2(card)==type&&lib.filter.cardDiscardable.apply(this,arguments); - }, - prompt:str+=(get.translation(card)+',是否弃置一张'+get.translation(type)+'为其助战?'), - position:'h', - _global_waiting:true, - id:id, - id2:id2, - ai:function(cardx){ - var info=get.info(card); - if(info&&info.ai&&info.ai.yingbian){ - var ai=info.ai.yingbian(card,source,targets,player); - if(!ai) return 0; - return ai-get.value(cardx); - } - else if(get.attitude(player,source)<=0) return 0; - return 5-get.value(cardx); - }, - }); - if(game.online){ - _status.event._resultid=id; - game.resume(); - } - }; + var yingbianCondition=event.yingbianConditions[num]; + if(event.temporaryYingbian.includes(yingbianCondition)||get.cardtag(card,`yingbian_${yingbianCondition}`)) lib.yingbian.condition.complex.get(yingbianCondition)(trigger); + else event.goto(3); 'step 2' - var type=get.type2(card); - var list=game.filterPlayer(function(current){ - if(current==player) return false; - if(!current.countCards('h')) return false; - return _status.connectMode||current.countCards('h',function(cardx){ - return get.type2(cardx)==type; - }) - }); - event.list=list; - event.id=get.id(); - list.sort(function(a,b){ - return get.distance(event.source,a,'absolute')-get.distance(event.source,b,'absolute'); - }); + if(result.bool) event.goto(4); 'step 3' - if(event.list.length==0){ - event.finish(); - return; - } - else if(_status.connectMode&&(event.list[0].isOnline()||event.list[0]==game.me)){ - event.goto(5); - } - else{ - event.current=event.list.shift(); - event.send(event.current,event.card,player,trigger.targets,event.id,trigger.parent.id); - } + event.num++; + if(event.num{ + if(!event.temporaryYingbian.includes(key)&&!get.cardtag(card,`yingbian_${key}`)) return; + game.yingbianEffect(trigger,value); + if(!yingbianEffectExecuted) yingbianEffectExecuted=true; + }); + if(!yingbianEffectExecuted){ + var defaultYingbianEffect=get.defaultYingbianEffect(card); + if(lib.yingbian.effect.has(defaultYingbianEffect)){ + game.yingbianEffect(trigger,lib.yingbian.effect.get(defaultYingbianEffect)); + if(!yingbianEffectExecuted) yingbianEffectExecuted=true; } } - event.withol=withol; - 'step 6' - if(result&&result.bool&&!event.zhuzhanresult){ - game.broadcast('cancel',event.id); - event.zhuzhanresult=game.me; - event.zhuzhanresult2=result; - } - 'step 7' - if(event.withol&&!event.resultOL){ - game.pause(); - } - 'step 8' - for(var i=0;ievent.target!=player, + logTarget:'player', + content:()=>{ + trigger.deniedGift.add(trigger.card); }, ai:{ - refuseGifts:true, - }, + refuseGifts:true + } }, xinge:{ audio:true, @@ -449,7 +449,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ } }, qixingbaodao:{ - trigger:{player:'equipAfter'}, + trigger:{player:'equipBegin'}, forced:true, equipSkill:true, filter:function(event,player){ @@ -595,6 +595,13 @@ game.import('card',function(lib,game,ui,get,ai,_status){ map.push([source,event.given_map[i]]); cards.addArray(event.given_map[i]); } + player.showCards(cards,`${get.translation(player)}对${(targets=>{ + if(get.itemtype(targets)=='player') targets=[targets]; + if(targets[0]!=player) return get.translation(targets); + const selfTargets=targets.slice(); + selfTargets[0]='自己'; + return get.translation(selfTargets); + })(logs)}发动了【${get.skillTranslation(event.name,player)}】`); game.loseAsync({ gain_list:map, player:player, @@ -606,82 +613,40 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, ai:{expose:0.1}, }, - _yongjian_zengyu:{ + _gifting:{ enable:'phaseUse', forceLoad:true, - filter:function(event,player){ - return player.hasCard((card)=>lib.skill._yongjian_zengyu.filterCard(card,player),'he'); - }, - filterCard:function(card,player){ - var mod=game.checkMod(card,player,'unchanged','cardZengyuable',player); - if(mod!='unchanged') return mod; - return get.position(card)=='h'&&get.cardtag(card,'gifts'); - }, - filterTarget:function(card,player,target){ - if(player==target) return false; - var card=ui.selected.cards[0]; - if(get.type(card,false)=='equip'){ - return target.canEquip(card,true); - } - return true; - }, + filter:(event,player)=>player.hasCard(card=>lib.skill._gifting.filterCard(card,player),lib.skill._gifting.position), + filterCard:(card,player)=>game.hasPlayer(current=>player.canGift(card,current,true)), + filterTarget:(card,player,target)=>ui.selected.cards.every(value=>player.canGift(value,target,true)), position:'he', discard:false, lose:false, delay:false, - check:function(card){ - var player=_status.event.player; - if(get.cardtag(card,'gifts')&&get.type(card,false)=='equip'&&game.hasPlayer(function(current){ - return current!=player&¤t.canEquip(card,true)&&!current.hasSkillTag('refuseGifts')&&get.effect(current,card,player,player)>0; - })) return 2; + check:card=>{ + const player=_status.event.player; + if(game.hasPlayer(current=>player.canGift(card,current,true)&&!current.refuseGifts(card,player)&&get.effect(current,card,player,player)>0)) return 2; if(!player.needsToDiscard()&&get.position(card)=='h') return 0; return 1+Math.random(); }, - content:function(){ - 'step 0' - if(event._zengyu_denied){ - player.loseToDiscardpile(cards); - } - else{ - if(get.type(cards[0],false)=='equip'){ - player.$give(cards[0],target,false); - game.delay(0.5); - target.equip(cards[0]); - } - else{ - target.gain(cards,player,'give'); - event.finish(); - } - } - 'step 1' - game.delayx(); + content:()=>{ + player.gift(cards,target); }, ai:{ - order:function(item,player){ - if(player.hasCard(function(card){ - return get.cardtag(card,'gifts')&&get.type(card,false)=='equip'&&game.hasPlayer(function(current){ - return current!=player&¤t.canEquip(card,true)&&!current.hasSkillTag('refuseGifts')&&get.effect(current,card,player,player)>0; - }); - },'h')) return 7; - return 0.51; - }, + order:(item,player)=>player.hasCard(card=>game.hasPlayer(current=>player.canGift(card,current,true)&&!current.refuseGifts(card,player)&&get.effect(current,card,player,player)>0),'h')?7:0.51, result:{ - target:function(player,target){ - var card=ui.selected.cards[0]; - if(!card||target.hasSkillTag('refuseGifts')) return 0; - if(get.type(card,false)=='equip') return get.effect(target,card,target,target); - if(card.name=='du') return player.hp>target.hp?-1:0; - if(target.hasSkillTag('nogain')) return 0; - return Math.max(1,get.value(card,player)-get.value(card,target)); - }, - }, - }, - }, + target:(player,target)=>{ + const result=ui.selected.cards.map(value=>player.getGiftAIResultTarget(value,target)); + return result.reduce((previousValue,currentValue)=>previousValue+currentValue,0)/result.length; + } + } + } + } }, translate:{ gifts_tag:'赠', du:'毒', - du_info:'①当此牌正面向上离开你的手牌区,或作为你的拼点牌而亮出时,你失去1点体力。②当你因摸牌或分发起始手牌而获得【毒】后,你可将其分配给其他角色(正面朝上移动,且不触发〖毒①〗)。', + du_info:'①当此牌正面向上离开你的手牌区,或作为你的拼点牌而亮出时,你失去1点体力。②当你因摸牌或分发起始手牌而获得【毒】后,你可展示之并交给其他角色(不触发〖毒①〗)。', g_du:'毒', g_du_give:'赠毒', du_given:'已分配', @@ -694,7 +659,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ yitianjian:'倚天剑', yitianjian_info:'当你因执行【杀】的效果而造成伤害后,若你已受伤,则你可弃置一张手牌,然后回复1点体力。', qixingbaodao:'七星宝刀', - qixingbaodao_info:'锁定技。当此牌进入你的装备区后,你弃置装备区和判定区内的所有其他牌。', + qixingbaodao_info:'锁定技。当此牌进入你的装备区时,你弃置装备区和判定区内的所有其他牌。', duanjian:'断剑', duanjian_info:'这是一把坏掉的武器…', duanjian_append:'不要因为手快而装给自己。', @@ -707,13 +672,13 @@ game.import('card',function(lib,game,ui,get,ai,_status){ yonglv_info:'锁定技。①你至其他角色的距离-1。②其他角色至你的距离视为1。', yonglv_append:'它旁边的就是王仲宣。', zhanxiang:'战象', - zhanxiang_info:'锁定技。①其他角色至你的距离+1。②当你成为〖赠予〗的目标后,你将此次赠予的效果改为“将赠予牌移动至弃牌堆”。', + zhanxiang_info:'锁定技。①其他角色至你的距离+1。②其他角色对你赠予的牌视为赠予失败。', xinge:'信鸽', xinge_info:'出牌阶段限一次。你可以将一张手牌交给一名其他角色。', xinge_append:'咕咕咕。', - _yongjian_zengyu:'赠予', - _yongjian_zengyu_info:'出牌阶段,你可将一张拥有“赠”标签的手牌区装备牌置于一名其他角色的装备区内,或将一张拥有“赠”标签的手牌区非装备牌正面朝上交给一名其他角色。', + _gifting:'赠予', + _gifting_info:'出牌阶段,你可将一张拥有“赠”标签的手牌区装备牌置于一名其他角色的装备区内,或将一张拥有“赠”标签的手牌区非装备牌正面朝上交给一名其他角色。', }, list:[ ['spade',1,'guaguliaodu'], diff --git a/card/yunchou.js b/card/yunchou.js index cf71b6945f..ca76a5e3c9 100644 --- a/card/yunchou.js +++ b/card/yunchou.js @@ -276,7 +276,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ enable:function(){ return game.countPlayer()>2; }, - chongzhu:function(){ + recastable:function(){ return game.countPlayer()<=2; }, multicheck:function(card,player){ diff --git a/card/zhenfa.js b/card/zhenfa.js index 501d878ac0..3a363ddc25 100644 --- a/card/zhenfa.js +++ b/card/zhenfa.js @@ -5,7 +5,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ card:{ pozhenjue:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:true, notarget:true, content:function(){ @@ -25,7 +25,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, changshezhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(card,player){ if(player.inline()) return true; if(player.identity=='unknown'||player.identity=='ye') return false; @@ -68,7 +68,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, tianfuzhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(){ return game.hasPlayer(function(current){ return current.isMajor(); @@ -94,7 +94,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, dizaizhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(){ return game.hasPlayer(function(current){ return current.isNotMajor(); @@ -121,7 +121,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, fengyangzhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:true, filterTarget:function(card,player,target){ return target.sieged(); @@ -142,7 +142,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, yunchuizhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:true, filterTarget:function(card,player,target){ return target.siege(); @@ -163,7 +163,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, qixingzhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(card,player){ return player.siege()||player.sieged(); }, @@ -202,7 +202,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, shepanzhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(card,player){ if(player.identity=='unknown'||player.identity=='ye') return false; if(get.population(player.identity)<=1) return false; @@ -231,7 +231,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, longfeizhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(card,player){ return player.next.siege(player); }, @@ -261,7 +261,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, huyizhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:function(card,player){ return player.siege(player.next)||player.siege(player.previous); }, @@ -309,7 +309,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, niaoxiangzhen:{ type:'zhenfa', - chongzhu:true, + recastable:true, enable:true, filterTarget:function(card,player,target){ if(player.identity==target.identity) return false; diff --git a/character/clan.js b/character/clan.js index 985ec60c71..9123c859be 100644 --- a/character/clan.js +++ b/character/clan.js @@ -43,6 +43,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ locked:true, content:function(){ 'step 0' + player.unmarkSkill('clanyuzhi'); var num1=0,num2=0,num3=0,bool=true; var history=player.actionHistory; for(var i=history.length-2;i>=0;i--){ @@ -92,7 +93,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.storage.clanyuzhi=lib.skill.dcweidang.getLength(result.cards[0]); player.markSkill('clanyuzhi'); } - else player.unmarkSkill('clanyuzhi'); }, ai:{ threaten:3, @@ -285,6 +285,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var storage=player.storage.clanjiexuan; return get.color(card)==((storage||0)%2?'black':'red'); }, + prompt:function(){ + if(_status.event.player.storage.clanjiexuan) return '将一张黑色牌当【过河拆桥】使用'; + return '将一张红色牌当【顺手牵羊】使用'; + }, skillAnimation:true, animationColor:'thunder', precontent:function(){ @@ -829,16 +833,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ clanSkill:true, filter:function(event,player){ if(!event.cards.length) return true; - var cards=[]; - game.countPlayer(current=>{ - if(!current.hasClan('太原王氏')) return false; - current.getHistory('lose',evt=>{ - if(event!=evt.getParent()) return false; - cards.addArray(evt.getl(current).hs); + return !game.hasPlayer2(current=>{ + if(!current.hasClan('太原王氏')&¤t!=player) return false; + return current.hasHistory('lose',evt=>{ + return evt.getParent()==event&&evt.hs.length>0; }); - }) - if(event.cards.some(card=>!cards.contains(card))) return false; - return true; + }); }, content:function(){ 'step 0' @@ -899,6 +899,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ global:'clanlianzhu_global', subSkill:{ global:{ + forceaudio:true, + audio:'clanlianzhu', enable:'phaseUse', filter:(event,player)=>game.hasPlayer(current=>lib.skill.clanlianzhu_global.filterTarget(null,player,current)), filterCard:(card,player)=>game.hasPlayer(current=>current.hasSkill('clanlianzhu')&&!current.hasSkill('clanlianzhu_targeted')&&!current.storage.clanlianzhu)&&player.canRecast(card), @@ -1935,11 +1937,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.hasCard(card=>get.suit(card)==get.suit(event.card)&&player.canRecast(card),'h'); }, content:function(){ + 'step 0' if(trigger.targets&&trigger.targets.length==1){ trigger.targets[0].link(true); } var cards=player.getCards('h',card=>get.suit(card)==get.suit(trigger.card)&&player.canRecast(card)); if(cards.length>0) player.recast(cards); + 'step 1' + player.draw(); } }, clanhuanyin:{ @@ -2024,6 +2029,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return 6-ui.selected.cards.length-get.value(card); }, onuse:function(links,player){ + lib.skill.chenliuwushi.change(player,-1); player.addTempSkill('clanzhanding_effect'); }, ai:{ @@ -2042,7 +2048,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return event.skill=='clanzhanding'; }, content:function(){ - lib.skill.chenliuwushi.change(player,-1); if(player.hasHistory('sourceDamage',function(evt){ return evt.card==trigger.card; })){ @@ -2269,6 +2274,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(player.storage.clanguangu) return '转换技,出牌阶段限一次。阴:你可以观看牌堆顶的至多四张牌;阳:你可以观看一名角色的至多四张手牌。然后你可以使用其中的一张牌。'; return '转换技,出牌阶段限一次。阴:你可以观看牌堆顶的至多四张牌;阳:你可以观看一名角色的至多四张手牌。然后你可以使用其中的一张牌。'; }, + clanjiexuan:function(player){ + if(player.storage.clanjiexuan) return '限定技,转换技。阴:你可以将一张红色牌当【顺手牵羊】使用;阳:你可以将一张黑色牌当【过河拆桥】使用。'; + return '限定技,转换技。阴:你可以将一张红色牌当【顺手牵羊】使用;阳:你可以将一张黑色牌当【过河拆桥】使用。'; + }, }, translate:{ clan_wuxian:'族吴苋', @@ -2281,7 +2290,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ chenliuwushi:'陈留·吴氏', clan_wuban:'族吴班', clanzhanding:'斩钉', - clanzhanding_info:'你可以将任意张牌当做【杀】使用。你以此法使用的【杀】结算结束后,你令你的手牌上限-1,然后若你因此【杀】造成过伤害,则你将手牌摸至手牌上限(至多摸五张),否则你令此【杀】不计入次数限制。', + clanzhanding_info:'你可以将任意张牌当做【杀】使用并你令你的手牌上限-1。你以此法使用的【杀】结算结束后,若你因此【杀】造成过伤害,则你将手牌摸至手牌上限(至多摸五张),否则你令此【杀】不计入次数限制。', clan_xunshu:'族荀淑', clanshenjun:'神君', clanshenjun_info:'当一名角色使用【杀】或普通锦囊牌时,若你手牌中有该牌名的牌,你展示之,且这些牌称为“神君”。然后本阶段结束时,你可以将等同于你“神君”数张牌当做一张“神君”牌使用。', diff --git a/character/collab.js b/character/collab.js index 5de2d131dd..b2739cf665 100644 --- a/character/collab.js +++ b/character/collab.js @@ -982,7 +982,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, content:function(){ if(trigger.name=='lose'){ - trigger.cards.remove(player.getEquips('ruyijingubang')); + trigger.cards.removeArray(player.getEquips('ruyijingubang')); } else{ while(trigger.slots.contains('equip1')) trigger.slots.remove('equip1'); diff --git a/character/ddd.js b/character/ddd.js index d48918391f..c658ac3475 100644 --- a/character/ddd.js +++ b/character/ddd.js @@ -117,7 +117,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ target.useCard(result.targets,card,event.links); } else{ - target.recast(event.links,(player,cards)=>game.cardsDiscard(cards).cards); + target.recast(event.links,(player,cards)=>game.cardsDiscard(cards)); } 'step 4' for(var card of cards){ @@ -3864,17 +3864,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ discard:function(){ "step 0" game.log(player,'进入了弃牌阶段'); - event.num=(function(){ - var num=0; - var hs=player.getCards('he'); - num+=hs.length; - for(var i=0;i!player.canIgnoreHandcard(card))-player.getHandcardLimit()); if(event.num<=0) event.finish(); else{ if(lib.config.show_phase_prompt){ diff --git a/character/diy.js b/character/diy.js index cc31e6c906..69649956ad 100755 --- a/character/diy.js +++ b/character/diy.js @@ -1243,20 +1243,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ lose:false, delay:false, promptfunc:()=>'出牌阶段,你可以赠予一张“米券”,然后执行一项本回合内未被选择过的效果:⒈对其造成1点伤害;⒉摸两张牌;⒊弃置其的两张牌;⒋亮出牌堆顶的一张牌,然后你可以使用之。', - check:function(card){ - var player=_status.event.player; - if(get.cardtag(card,'gifts')&&get.type(card,false)=='equip'&&game.hasPlayer(function(current){ - return current!=player&¤t.canEquip(card,true)&&!current.hasSkillTag('refuseGifts')&&get.effect(current,card,player,player)>0; - })) return 2; - return 1+Math.random(); + check:card=>{ + const player=_status.event.player; + return get.type(card,false)=='equip'&&game.hasPlayer(current=>player.canGift(card,current,true)&&!current.refuseGifts(card,player)&&get.effect(current,card,player,player)>0)?2:1+Math.random(); }, content:function(){ 'step 0' - var next=game.createEvent('_yongjian_zengyu'); - next.player=player; - next.target=target; - next.cards=cards; - next.setContent(lib.skill._yongjian_zengyu.content); + player.gift(cards,target); 'step 1' var list=player.getStorage('minagi_peiquan_yukito'); if(list.length>=4) event.finish(); @@ -1300,12 +1293,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ai:{ order:4, result:{ - player:function(player,target){ - var baseEffect=Math.min(3,get.effect(target,'_yongjian_zengyu',player,player)); - var choices=['damage','draw','discard','use']; + player:(player,target)=>{ + const giftEffects=ui.selected.cards.map(value=>player.getGiftEffect(value,target)); + const baseEffect=Math.min(3,giftEffects.reduce((previousValue,currentValue)=>previousValue+currentValue,0)/giftEffects.length); + const choices=['damage','draw','discard','use']; choices.removeArray(player.getStorage('minagi_peiquan_yukito')); if(choices.length<=0) return baseEffect; - var eff=Math.max.apply(Math,choices.map(function(choice){ + return baseEffect+Math.max(...choices.map(choice=>{ switch(choice){ case 'damage':return get.damageEffect(target,player,player); case 'draw':return get.effect(player,{name:'wuzhong'},player,player); @@ -1313,9 +1307,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ case 'use':return _status.event.getRand('minagi_peiquan')*4; } })); - return baseEffect+eff; - }, - }, + } + } }, group:'minagi_peiquan_umareta', subSkill:{ @@ -4269,25 +4262,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, asara_yingwei:{ - trigger:{player:'useCard1'}, + trigger:{player:'yingbian'}, forced:true, - filter:function(event,player){ - return player.getHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].contains('asara_yingwei')) return true; - } - return false; - }).length>0; - }, - content:function(){ - if(!trigger.card.yingbian){ - trigger.card.yingbian=true; - var info=get.info(trigger.card); - if(info&&info.yingbian) info.yingbian(trigger); - player.addTempSkill('yingbian_changeTarget'); - } - }, + filter:(event,player)=>event.card.isCard&&player.hasHistory('lose',evt=>evt.getParent()==event&&Object.values(evt.gaintag_map).some(value=>value.includes('asara_yingwei'))), + content:()=>{ + trigger.forceYingbian=true; + } }, yukito_kongwu:{ enable:'phaseUse', @@ -6265,16 +6245,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, phaseDiscardContent:function(){ "step 0" - var num=0; - var hs=player.getCards('he'); - num+=hs.length; - for(var i=0;i!player.canIgnoreHandcard(card))-player.getHandcardLimit()); if(event.num<=0) event.finish(); else{ if(lib.config.show_phase_prompt){ @@ -8523,7 +8494,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return true; } else if(event.name=='gain'){ - if(event.giver||event.getParent().name=='_yongjian_zengyu') return false; + if(event.giver||event.getParent().name=='gift') return false; var cards=event.getg(event.player); if(!cards.length) return false; return game.hasPlayer(function(current){ diff --git a/character/extra.js b/character/extra.js index d6246f22ba..0f8b42c0d8 100755 --- a/character/extra.js +++ b/character/extra.js @@ -18,7 +18,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ extra_mobilezhi:['shen_guojia','shen_xunyu'], extra_mobilexin:['shen_taishici','shen_sunce'], extra_tw:['tw_shen_guanyu','tw_shen_lvmeng'], - extra_offline:['shen_diaochan','boss_zhaoyun'], + extra_offline:['shen_diaochan','boss_zhaoyun','shen_dianwei'], }, }, character:{ @@ -1010,9 +1010,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ else if(lib.translate[name+'_info']){ str+=(''+lib.translate[name+'_info']+'|'); } - if(lib.card[name].yingbian_prompt&&get.is.yingbian(node)){ - if(typeof lib.card[name].yingbian_prompt=='function') str+=('应变:'+lib.card[name].yingbian_prompt(node)+'|'); - else str+=('应变:'+lib.card[name].yingbian_prompt+'|'); + if(get.is.yingbianConditional(node)){ + const yingbianEffects=get.yingbianEffects(node); + if(!yingbianEffects.length){ + const defaultYingbianEffect=get.defaultYingbianEffect(node); + if(lib.yingbian.prompt.has(defaultYingbianEffect)) yingbianEffects.push(defaultYingbianEffect); + } + if(yingbianEffects.length) str+=`应变:${yingbianEffects.map(value=>lib.yingbian.prompt.get(value)).join(';')}|`; } return str; }, @@ -2337,199 +2341,39 @@ game.import('character',function(lib,game,ui,get,ai,_status){ group:'hina_shenshi_yingbian', }, hina_shenshi_yingbian:{ - trigger:{player:'useCard1'}, + trigger:{player:'yingbian'}, forced:true, - filter:function(event,player){ - return event.cards.length==1&&!event.card.yingbian&&player.hasHistory('lose',function(evt){ - if(evt.getParent()!=event) return false; - for(var i in evt.gaintag_map){ - if(evt.gaintag_map[i].contains('hina_shenshi')) return true; - } - return false; - })&&Array.isArray(get.info(event.card).yingbian_tags); - }, - content:function(){ - if(!trigger.card.yingbian){ - trigger.card.yingbian=true; - var info=get.info(trigger.card); - trigger.card.cardtags=info.yingbian_tags.map(function(i){ - return 'yingbian_'+i; - }); - if(info&&info.yingbian) info.yingbian(trigger); - player.addTempSkill('yingbian_changeTarget'); - } - }, + filter:(event,player)=>event.card.isCard&&player.hasHistory('lose',evt=>evt.getParent()==event&&Object.values(evt.gaintag_map).some(value=>value.includes('hina_shenshi'))), + content:()=>{ + if(!Array.isArray(trigger.temporaryYingbian)) trigger.temporaryYingbian=[]; + trigger.temporaryYingbian.add('force'); + trigger.temporaryYingbian.addArray(get.yingbianEffects()); + } }, hina_xingzhi:{ groupSkill:true, - trigger:{player:'useCard1'}, + trigger:{player:'yingbian'}, usable:1, - filter:function(event,player){ - return player.group=='key'&&!event.card.yingbian&&Array.isArray(get.info(event.card).yingbian_tags); - }, - content:function(){ + filter:(event,player)=>player.group=='key'&&!event.card.yingbian&&lib.yingbian.condition.complex.has('zhuzhan'), + content:()=>{ 'step 0' - var info=get.info(trigger.card); - trigger.card.cardtags=info.yingbian_tags.map(function(i){ - return 'yingbian_'+i; - }); - event.card=trigger.card; - event._global_waiting=true; - event.send=function(player,card,source,targets,id,id2,skillState){ - if(skillState){ - player.applySkills(skillState); - } - var type=get.type2(card); - var str=get.translation(source); - if(targets&&targets.length){ - str+='对'; - str+=get.translation(targets); - } - str+='使用了'; - var next=player.chooseCard({ - filterCard:function(card){ - return get.type2(card)==type&&lib.filter.cardDiscardable.apply(this,arguments); - }, - prompt:str+=(get.translation(card)+',是否弃置一张'+get.translation(type)+'为其助战?'), - position:'h', - _global_waiting:true, - id:id, - id2:id2, - ai:function(cardx){ - var info=get.info(card),num=0; - if(info&&info.ai&&info.ai.yingbian){ - var ai=info.ai.yingbian(card,source,targets,player); - if(ai) num=ai; - } - if(get.attitude(player,source)<=0) return 0; - return Math.max(ai,6)-get.value(cardx); - }, - }); - if(game.online){ - _status.event._resultid=id; - game.resume(); - } + trigger.yingbianZhuzhanAI=(player,card,source,targets)=>cardx=>{ + if(get.attitude(player,source)<=0) return 0; + var info=get.info(card),num=0; + if(info&&info.ai&&info.ai.yingbian){ + var ai=info.ai.yingbian(card,source,targets,player); + if(ai) num=ai; + } + return Math.max(num,6)-get.value(cardx); }; + trigger.afterYingbianZhuzhan=event=>event.zhuzhanresult.draw(2); + lib.yingbian.condition.complex.get('zhuzhan')(trigger); 'step 1' - var type=get.type2(card); - var list=game.filterPlayer(function(current){ - if(current==player) return false; - if(!current.countCards('h')) return false; - return _status.connectMode||current.countCards('h',function(cardx){ - return get.type2(cardx)==type; - }) - }); - event.list=list; - event.id=get.id(); - list.sort(function(a,b){ - return get.distance(event.source,a,'absolute')-get.distance(event.source,b,'absolute'); - }); - 'step 2' - if(event.list.length==0){ - event.finish(); - return; - } - else if(_status.connectMode&&(event.list[0].isOnline()||event.list[0]==game.me)){ - event.goto(4); - } - else{ - event.current=event.list.shift(); - event.send(event.current,event.card,player,trigger.targets,event.id,trigger.parent.id); - } - 'step 3' - if(result.bool){ - event.zhuzhanresult=event.current; - event.zhuzhanresult2=result; - if(event.current!=game.me) game.delayx(); - event.goto(8); - } - else{ - event.goto(2); - } - 'step 4' - var id=event.id; - var sendback=function(result,player){ - if(result&&result.id==id&&!event.zhuzhanresult&&result.bool){ - event.zhuzhanresult=player; - event.zhuzhanresult2=result; - game.broadcast('cancel',id); - if(_status.event.id==id&&_status.event.name=='chooseCard'&&_status.paused){ - return (function(){ - event.resultOL=_status.event.resultOL; - ui.click.cancel(); - if(ui.confirm) ui.confirm.close(); - }); - } - } - else{ - if(_status.event.id==id&&_status.event.name=='chooseCard'&&_status.paused){ - return (function(){ - event.resultOL=_status.event.resultOL; - }); - } - } - }; - - var withme=false; - var withol=false; - var list=event.list; - for(var i=0;igame.yingbianEffect(trigger,value)); + player.addTempSkill('yingbian_changeTarget'); + } }, yingba:{ audio:2, @@ -2985,7 +2829,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 'step 1' if(result.control!='cancel2'){ if(result.control=='选项二'){ - player.logSkill('tspowei',target); + player.logSkill('tspowei_use',target); player.gainPlayerCard(target,'h',true); event.goto(3); } @@ -5964,6 +5808,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ evt.cards&&evt.cards.length==2&&_status.currentPhase&&_status.currentPhase!=player&&_status.currentPhase.countDiscardableCards(player,'he'); }, content:function(){ + //game.log(trigger.card) + //game.log(trigger.cards) player.line(_status.currentPhase,'green'); player.discardPlayerCard(_status.currentPhase,'he',true); } diff --git a/character/hearth.js b/character/hearth.js index dc6a64cac7..6099402400 100644 --- a/character/hearth.js +++ b/character/hearth.js @@ -8470,22 +8470,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 'step 1' if(result.bool&&result.cards.length){ target.recast(result.cards,null,(player,cards)=>{ - var type=get.type(result.cards[0],'trick'); - var name=result.cards[0].name; - var card2=get.cardPile(function(card){ - return get.type(card,'trick')==type&&card.name!=name; - }); - if(!card2){ - card2=get.cardPile(function(card){ - return get.type(card,'trick')==type; - }); - } - if(card2){ - target.gain(card2,'draw'); - } - else{ - target.draw().log=false; - } + var type=get.type(cards[0],'trick'),name=cards[0].name,card2=get.cardPile(card=>get.type(card,'trick')==type&&card.name!=name); + if(!card2) card2=get.cardPile(card=>get.type(card,'trick')==type); + if(card2) player.gain(card2,'draw'); + else player.draw().log=false; }); var clone=game.createCard(card); player.gain(clone,'gain2'); diff --git a/character/huicui.js b/character/huicui.js index 217bb55eac..511b235f03 100644 --- a/character/huicui.js +++ b/character/huicui.js @@ -11,9 +11,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ zhangkai:['male','qun',4,['dcxiangshu']], gaoxiang:['male','shu',4,['dcchiying'],['unseen']], yuanyin:['male','qun',3,['dcmoshou','dcyunjiu'],['unseen']], - dongwan:['female','qun',3,['dcshengdu','dcjieling'],['unseen']], + dongwan:['female','qun',3,['dcshengdu','dcjieling']], zhangchu:['female','qun',3,['dcjizhong','dcrihui','dcguangshi']], - peiyuanshao:['male','qun',4,['dcmoyu'],['unseen']], + peiyuanshao:['male','qun',4,['dcmoyu']], mengjie:['male','qun',3,['dcyinlu','dcyouqi']], dc_huojun:['male','shu',4,['dcgue','dcsigong']], dc_sunhanhua:['female','wu',3,['dchuiling','dcchongxu']], @@ -613,38 +613,39 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return game.hasPlayer(current=>{ if(current==player||current==event.player) return false; return current.hasHistory('lose',function(evt){ - return evt.cards.length>0; + return evt.cards2.length>0; }); })&&(_status.connectMode||player.hasCard({type:'basic'},'h')); }, direct:true, content:function(){ 'step 0' + var map={}; + game.countPlayer(function(current){ + if(current==player||current==trigger.player) return false; + if(current.hasHistory('lose',function(evt){ + return evt.cards2.length>0; + })) map[current.playerid]=Math.min(5,current.getHistory('lose').reduce(function(num,evt){ + return num=evt.cards2.length; + },0))+1; + }); player.chooseCardTarget({ prompt:get.prompt('dcporui'), - //prompt2:'弃置一张基本牌并选择一名本回合失去过牌的非当前回合的其他角色,你视为对其依次使用'+get.cnNumber(Math.max(0,player.hp)+1)+'张【杀】', prompt2:get.skillInfoTranslation('dcporui',player), - filterCard:lib.filter.cardDiscardable, - selectCard:1, + filterCard:function(card,player){ + return get.type2(card)=='basic'&&lib.filter.cardDiscardable(card,player,'dcporui'); + }, position:'he', - list:game.filterPlayer(current=>{ - if(current==player||current==trigger.player) return false; - return current.hasHistory('lose',function(evt){ - return evt.cards.length>0; - }); - }), filterTarget:function(card,player,target){ - return _status.event.list.map(i=>i[0]).contains(target); + return Object.keys(_status.event.map).contains(target.playerid); }, ai1:function(card){ return 7-get.value(card); }, ai2:function(target){ - return get.effect(target,{name:'sha'},_status.event.player,_status.event.player)*_status.event.list.find(i=>{ - return i[0]==target; - })[1]; + return get.effect(target,{name:'sha'},_status.event.player,_status.event.player)*_status.event.map[target.playerid]; } - }); + }).set('map',map); 'step 1' if(result.bool){ var target=result.targets[0],cards=result.cards; @@ -884,12 +885,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ target.chooseToUse(function(card,player,event){ if(get.name(card)!='sha') return false; return lib.filter.filterCard.apply(this,arguments); - },'是否对'+get.translation(player)+'使用一张【杀】(伤害基数为'+num+')?').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ + },'是否对'+get.translation(player)+'使用一张无距离限制的【杀】(伤害基数为'+num+')?').set('targetRequired',true).set('complexSelect',true).set('filterTarget',function(card,player,target){ if(target!=_status.event.sourcex&&!ui.selected.targets.contains(_status.event.sourcex)) return false; - return lib.filter.filterTarget.apply(this,arguments); + return lib.filter.targetEnabled.apply(this,arguments); }).set('sourcex',player).set('num',num).set('oncard',card=>{ - var evt=_status.event; - evt.baseDamage=evt.num; + _status.event.baseDamage=_status.event.getParent().num; }); 'step 2' if(result.bool){ @@ -903,7 +903,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ charlotte:true, onremove:true, }, - ban:{charlotte:true}, + ban:{ + charlotte:true, + mark:true, + marktext:'欲', + intro:{content:'偷马贼被反打了!'}, + }, ai:{ ai:{ effect:{ @@ -936,7 +941,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ target:player, card:{name:'sha'}, },true)) return eff; - if(player.getStorage('dcmoyu_clear').length||player.hp+player.countCards('hs','tao')<=1) return 0; + if(target.hasSha()&&player.hp+player.countCards('h',function(card){ + var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); + if(mod2!='unchanged') return mod2; + var mod=game.checkMod(card,player,player,'unchanged','cardSavable',player); + if(mod!='unchanged') return mod; + var savable=get.info(card).savable; + if(typeof savable=='function') savable=savable(card,player,player); + return savable; + })<=player.getStorage('dcmoyu_clear').length+1) return 0; return eff; } } @@ -1147,16 +1160,19 @@ game.import('character',function(lib,game,ui,get,ai,_status){ targetInRange:function(card){ if(card.storage&&card.storage.dcjieling) return true; }, + cardUsable:function(card,player,num){ + if(card.storage&&card.storage.dcjieling) return Infinity; + }, }, subSkill:{ after:{ - trigger:{global:'useCardAfter'}, - forced:true, - direct:true, charlotte:true, + audio:'dcjieling', + trigger:{global:'useCardAfter'}, filter:function(event,player){ return event.card.name=='sha'&&event.card.storage&&event.card.storage.dcjieling; }, + direct:true, content:function(){ 'step 0' var damaged=game.hasPlayer2(current=>{ @@ -6459,10 +6475,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, mod:{ targetInRange:function(card,player,target){ - for(var i=1;i<=5;i++){ - if(!player.hasDisabledSlot(i)) return false; - } - return true; + if(!player.hasEnabledSlot()) return true; }, }, marktext:'萍', @@ -10196,7 +10209,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcsigong_info:'其他角色的回合结束时,若其于本回合内使用牌被响应过,你可以将手牌摸至或弃置至1,视为对其使用一张需使用X张【闪】抵消的【杀】,且此【杀】的伤害基数+1(X为你以此法弃置的牌数且至少为1)。当你以此法造成伤害后,该技能于本轮失效。', peiyuanshao:'裴元绍', dcmoyu:'没欲', - dcmoyu_info:'出牌阶段每名角色限一次。你可以获得一名其他角色区域里的一张牌,然后其可以对你使用一张【杀】,且此【杀】伤害基数为X(X为你于本回合发动此技能的次数)。若此【杀】对你造成了伤害,你令此技能于本回合失效。', + dcmoyu_info:'出牌阶段每名角色限一次。你可以获得一名其他角色区域里的一张牌,然后其可以对你使用一张无距离限制的【杀】,且此【杀】伤害基数为X(X为你于本回合发动此技能的次数)。若此【杀】对你造成了伤害,你令此技能于本回合失效。', zhangchu:'张楚', dcjizhong:'集众', dcjizhong_info:'出牌阶段限一次。你可以令一名其他角色摸两张牌,然后其选择一项:1.若其没有“信众”标记,其获得“信众”标记;2.弃置三张手牌。', diff --git a/character/jsrg.js b/character/jsrg.js index 03b69f47ac..435aa9091e 100644 --- a/character/jsrg.js +++ b/character/jsrg.js @@ -29,13 +29,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ //承 jsrg_sunce:['male','wu',4,['jsrgduxing','jsrgzhiheng','jsrgzhasi','jsrgbashi'],['zhu']], jsrg_xuyou:['male','wei',3,['jsrglipan','jsrgqingxi','jsrgjinmie'],['doublegroup:wei:qun']], - jsrg_lvbu:['male','qun',5,['jsrgwuchang','jsrgqingjiao','jsrgchengxu'],['doublegroup:qun:shu']], - jsrg_zhanghe:['male','wei',4,['jsrgqiongtu','jsrgxianzhu'],['doublegroup:qun:wei']], + jsrg_lvbu:['male','qun',5,['jsrgwuchang','jsrgqingjiao','jsrgchengxu'],['doublegroup:shu:qun']], + jsrg_zhanghe:['male','wei',4,['jsrgqiongtu','jsrgxianzhu'],['doublegroup:wei:qun']], jsrg_zoushi:['female','qun',3,['jsrgguyin','jsrgzhangdeng']], - jsrg_guanyu:['male','shu',5,['jsrgguanjue','jsrgnianen']], + jsrg_guanyu:['male','shu',5,['jsrgguanjue','jsrgnianen'],['border:wei']], jsrg_chendeng:['male','qun',3,['jsrglunshi','jsrgguitu']], jsrg_zhenji:['female','qun',3,['jsrgjixiang','jsrgchengxian']], - jsrg_zhangliao:['male','qun',4,['jsrgzhengbing','jsrgtuwei'],['doublegroup:qun:wei']], + jsrg_zhangliao:['male','qun',4,['jsrgzhengbing','jsrgtuwei'],['doublegroup:wei:qun']], jsrg_xugong:['male','wu',3,['jsrgbiaozhao','jsrgyechou']], jsrg_chunyuqiong:['male','qun',4,['jsrgcangchu','jsrgshishou']], }, @@ -84,7 +84,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ai:{ order:5, result:{ - target:function(player,target){ + player:function(player,target){ var eff=Math.sign(get.effect(target,{name:'juedou'},player,player)); if(player.hasSkillTag('directHit_ai',true,{ target:target, @@ -92,10 +92,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ },true)||ui.selected.targets.concat(target).reduce((p,c)=>{ return p+c.countCards('h'); },0)player.countCards('h')?'tuixinzhifu':'chenghuodajie'); + var list=[]; + if(ui.selected.cards.length) list.addArray(ui.selected.cards); + var card=get.autoViewAs({name:name},list); + return get.effect(target,card,player,player); + }, + }, + }, subSkill:{ tuixinzhifu:{ charlotte:true, @@ -1240,7 +1254,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ event.asked=true; player.chooseButton([ '###'+get.prompt('jsrgjixiang',trigger.player)+'###
'+str+'
', - [listx,'vcard'] + [listx,'vcard'], ]).set('ai',()=>Math.random()+1); } 'step 1' @@ -1248,6 +1262,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var name=result.links[0][2],nature=result.links[0][3]; var card={name:name,nature:nature,isCard:true}; event.card=card; + var evt=trigger.getParent(); var reason=(trigger.name=='chooseToUse'?'使用':'打出'); var prompt=event.asked? '济乡:是否弃置一张牌'+(trigger.filterTarget?'并选择目标角色':'')+'?': @@ -1467,8 +1482,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return player.group=='qun'; }, filterCard:lib.filter.cardRecastable, - check:function(card,player){ - var val=5+['shan','tao'].contains(get.name(card))*1.5; + check:function(card){ + var player=_status.event.player,val=5+['shan','tao'].contains(get.name(card))*1.5; if(player.needsToDiscard()>2&&get.name(card)=='sha'&&player.countCards('hs','sha')>1) val+=0.5; return val-get.value(card); }, @@ -1526,13 +1541,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ 'step 0' player.chooseTarget(get.prompt('jsrgtuwei'),'获得攻击范围内任意名角色的各一张牌。然后回合结束时这些角色中未受过伤害的角色依次获得你的一张牌。',(card,player,target)=>{ - return player.inRange(current)&&target.countGainableCards(player,'he')>0; + return player.inRange(target)&&target.countGainableCards(player,'he')>0; },[1,Infinity]).set('ai',target=>{ var player=_status.event.player; - return get.effect(target,{name:'shunshou'},player,player); - }).set('damage',player.hasCard(card=>{ - return player.hasValueTarget(card)&&get.tag(card,'damage'); - },'hs')); + return get.effect(target,{name:'shunshou_copy2'},player,player); + }); 'step 1' if(result.bool){ var targets=result.targets.slice(); @@ -1831,7 +1844,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, //江山如故·起 sbyingmen:{ - forbid:['guozhan'], trigger:{ global:'phaseBefore', player:'enterGame', @@ -1880,8 +1892,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, addVisitors:function(characters,player){ player.addSkillBlocker('sbyingmen'); - game.log(player,'将','#y'+get.translation(characters),'加入了','#g“访客”') - lib.skill.rehuashen.drawCharacter(player,characters); + game.log(player,'将','#y'+get.translation(characters),'加入了','#g“访客”'); + game.broadcastAll(function(player,characters){ + player.$draw(characters.map(function(name){ + var cardname='huashen_card_'+name; + lib.card[cardname]={ + fullimage:true, + image:'character:'+name + }; + lib.translate[cardname]=get.rawName2(name); + return game.createCard(cardname,' ',' '); + }),'nobroadcast'); + },player,characters); player.markAuto('sbyingmen',characters) var storage=player.getStorage('sbyingmen'); var skills=lib.skill.sbyingmen.getSkills(storage,player); @@ -2807,7 +2829,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ forced:true, locked:false, getNum:function(target,player){ - return target.countCards(card=>{ + return target.countCards('e',card=>{ var subtype=get.subtypes(card); for(var i of subtype){ if(player.hasDisabledSlot(i)) return true; @@ -2883,6 +2905,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }); } + else{ + event.finish(); + return; + } 'step 2' if(result.bool){event.finish();return;} var targets=game.filterPlayer(current=>{ diff --git a/character/mobile.js b/character/mobile.js index 0710cc01b7..43c04cc36d 100644 --- a/character/mobile.js +++ b/character/mobile.js @@ -6,23 +6,31 @@ game.import('character',function(lib,game,ui,get,ai,_status){ connect:true, characterSort:{ mobile:{ - mobile_default:["miheng","taoqian","lingcao","sunru","lifeng","zhuling","liuye","zhaotongzhaoguang","majun","simazhao","wangyuanji","pangdegong","shenpei","hujinding","zhangyì","jiakui","yangbiao","chendeng","dongcheng","yangyi","dengzhi","zhengxuan","sp_sufei","furong","dingyuan","simashi","yanghuiyu","hucheer","gongsunkang","nanhualaoxian","zhouqun","qiaozhou","fuqian","simafu","mayuanyi","yanpu","sunhanhua","sp_maojie","peixiu","sp_jianggan","ruanhui","xin_mamidi","sp_caosong","yangfu","wangjun","sp_pengyang","qianzhao","old_wanglang",'shichangshi'], + mobile_default:['xin_guozhao',"miheng","taoqian","lingcao","sunru","lifeng","zhuling","liuye","zhaotongzhaoguang","majun","simazhao","wangyuanji","pangdegong","shenpei","hujinding","zhangyì","jiakui","yangbiao","chendeng","dongcheng","yangyi","dengzhi","zhengxuan","sp_sufei","furong","dingyuan","simashi","yanghuiyu","hucheer","gongsunkang","nanhualaoxian","zhouqun","qiaozhou","fuqian","simafu","mayuanyi","yanpu","sunhanhua","sp_maojie","peixiu","sp_jianggan","ruanhui","xin_mamidi","sp_caosong","yangfu","wangjun","sp_pengyang","qianzhao","old_wanglang",'shichangshi'], mobile_yijiang:["yj_zhanghe","yj_zhangliao","yj_xuhuang","yj_ganning",'yj_huangzhong','yj_weiyan'], - mobile_sunben:["re_sunben"], mobile_standard:["xin_xiahoudun","xin_zhangfei"], - mobile_shenhua:["re_pangtong","re_guanqiujian","xin_yuanshao","re_liushan","re_dongzhuo","re_sp_zhugeliang","re_sunjian","re_dengai","re_jiangwei","re_zhurong","re_caiwenji","re_xunyu","re_dianwei","xin_zhoutai","re_yanwen",'re_zhangzhang'], + mobile_shenhua_feng:['re_xiaoqiao',"xin_zhoutai"], + mobile_shenhua_huo:["re_pangtong","re_sp_zhugeliang","re_xunyu","re_dianwei","re_yanwen","xin_yuanshao"], + mobile_shenhua_lin:["re_dongzhuo","re_sunjian","re_zhurong"], + mobile_shenhua_shan:["re_liushan","re_dengai","re_jiangwei","re_caiwenji",'re_zhangzhang',"re_sunben"], + mobile_shenhua_yin:['xin_sunliang'], + mobile_shenhua_lei:["re_guanqiujian"], mobile_yijiang1:["re_xusheng","re_lingtong","ol_yujin","re_wuguotai","re_gaoshun",'re_caozhi'], mobile_yijiang2:["xin_liaohua","xin_caozhang","re_liubiao","re_handang","xin_chengpu","xin_gongsunzan","re_zhonghui","re_bulianshi"], mobile_yijiang3:["re_liru","xin_jianyong","xin_zhuran","xin_guohuai","xin_panzhangmazhong","xin_fuhuanghou","re_yufan"], mobile_yijiang4:["xin_zhoucang","xin_caifuren","xin_guyong","xin_sunluban","xin_caozhen","xin_jushou","xin_wuyi","xin_zhuhuan","re_chenqun"], - mobile_yijiang5:['xin_sunxiu','xin_quancong','xin_zhuzhi','xin_caoxiu'], + mobile_yijiang5:['xin_zhangyi','xin_sunxiu','xin_quancong','xin_zhuzhi','xin_caoxiu'], mobile_yijiang67:["re_jikang"], mobile_changshi:['scs_zhangrang','scs_zhaozhong','scs_sunzhang','scs_bilan','scs_xiayun','scs_hankui','scs_lisong','scs_duangui','scs_guosheng','scs_gaowang'], mobile_sp:["old_yuanshu","re_wangyun","re_baosanniang","re_weiwenzhugezhi","re_zhanggong","re_xugong","re_heqi","liuzan","xin_hansui"], }, }, character:{ - shichangshi:['male','qun',1,['mbdanggu','mbmowang']], + xin_guozhao:['female','wei',3,['yichong','wufei'],['unseen']], + xin_zhangyi:['male','shu',4,['xinwurong','shizhi'],['unseen']], + xin_sunliang:['male','wu',3,['xinzhizheng','xinkuizhu','xinlijun'],['zhu']], + re_xiaoqiao:['female','wu',3,['retianxiang','xinhongyan']], + shichangshi:['male','qun',1,['mbdanggu','mbmowang']], re_zhangzhang:['male','wu',3,['rezhijian','guzheng']], qianzhao:['male','wei',4,['mbshihe','mbzhenfu']], old_wanglang:['male','wei',3,['gushe','jici']], @@ -386,6 +394,377 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, skill:{ + //郭照 + yichong:{ + init:function(player){ + if(!lib.skill['yichong_'+player.playerid]){ + lib.skill['yichong_'+player.playerid]={ + onremove:true, + mark:true, + marktext:'雀', + intro:{ + markcount:function(storage){ + return (storage||0).toString(); + }, + content:function(storage){ + return '已被掠夺'+(storage||0)+'张牌'; + }, + }, + }; + lib.translate['yichong_'+player.playerid]='易宠'; + lib.translate['yichong_'+player.playerid+'_bg']='雀'; + } + }, + audio:2, + trigger:{player:'phaseZhunbeiBegin'}, + direct:true, + content:function(){ + 'step 0' + player.chooseTarget(get.prompt('meihun'),'选择一名其他角色并选择一个花色,获得其此花色的所有牌并令其获得“雀”标记',lib.filter.notMe).set('ai',function(target){ + var player=_status.event.player; + var att=get.attitude(player,target); + if(att>0) return 0; + var getNum=function(player){ + var list=[]; + for(var i of lib.suit) list.push((player.countCards('he',{suit:i})+3)); + return list.sort((a,b)=>b-a)[0]; + }; + return getNum(target)+target.countCards('h')/10; + }); + 'step 1' + if(result.bool){ + var target=result.targets[0]; + player.logSkill('yichong',target); + event.target=target; + player.chooseControl(lib.suit.slice(0).reverse()).set('prompt','请声明一个花色').set('ai',function(){ + var target=_status.event.target,cards=target.getCards('he'); + var suits=lib.suit.slice(0); + suits.sort(function(a,b){ + var num=function(suit){ + return cards.filter(function(card){ + return get.suit(card)==suit; + }).length; + }; + return num(b)-num(a); + }); + return suits[0]; + }).set('target',target); + } + else event.finish(); + 'step 2' + var suit=result.control; + player.chat(get.translation(suit+2)); + game.log(player,'选择了','#y'+get.translation(suit+2)); + player.storage.yichong=suit; + player.markSkill('yichong'); + game.broadcastAll(function(player,suit){ + if(player.marks.yichong) player.marks.yichong.firstChild.innerHTML=get.translation(suit); + },player,suit) + if(target.countCards('he',{suit:suit})) player.gain(target.getCards('he',{suit:suit}),target,'giveAuto'); + game.countPlayer(function(current){ + current.removeSkill('yichong_'+player.playerid); + if(current==target) target.addSkill('yichong_'+player.playerid); + }); + player.addTempSkill('yichong_clear',{player:'phaseBegin'}); + }, + onremove:true, + intro:{content:'拥有“雀”标记的角色获得$牌后,你获得之'}, + group:'yichong_gain', + subSkill:{ + gain:{ + audio:'yichong', + trigger:{global:['gainAfter','loseAsyncAfter']}, + filter:function(event,player){ + if(!player.storage.yichong) return false; + return game.hasPlayer(function(current){ + if(!event.getg(current).length||!current.hasSkill('yichong_'+player.playerid)) return false; + if(current.countMark('yichong_'+player.playerid)>=5) return false; + return event.getg(current).some(card=>get.suit(card,current)==player.storage.yichong&&lib.filter.canBeGained(card,current,player)); + }); + }, + forced:true, + content:function(){ + 'step 0' + var target=game.findPlayer(function(current){ + if(!trigger.getg(current).length||!current.hasSkill('yichong_'+player.playerid)) return false; + if(current.countMark('yichong_'+player.playerid)>=5) return false; + return trigger.getg(current).some(card=>get.suit(card,current)==player.storage.yichong&&lib.filter.canBeGained(card,current,player)); + }); + event.target=target; + var cards=trigger.getg(target).filter(card=>get.suit(card,target)==player.storage.yichong&&lib.filter.canBeGained(card,target,player)); + if(cards.length<=5-target.countMark('yichong_'+player.playerid)) event._result={bool:true,links:cards}; + else{ + var num=(5-target.countMark('yichong_'+player.playerid)); + player.chooseButton(['易宠:获得其中的'+get.cnNumber(num)+'张牌',cards],num,true).set('ai',function(button){ + return get.value(button.link); + }); + } + 'step 1' + if(result.bool){ + player.gain(result.links,target,'give'); + target.addMark('yichong_'+player.playerid,result.links.length,false); + } + }, + }, + clear:{ + charlotte:true, + onremove:function(player){ + game.countPlayer(function(current){ + current.removeSkill('yichong_'+player.playerid); + }); + }, + }, + }, + }, + wufei:{ + audio:2, + trigger:{player:['useCardToPlayered','damageEnd']}, + filter:function(event,player){ + var target=game.findPlayer(current=>current.hasSkill('yichong_'+player.playerid)); + if(!target) return false; + if(event.name=='damage') return target.hp>Math.max(1,player.hp); + return event.isFirstTarget&&(event.card.name=='sha'||(get.type(event.card)=='trick'&&get.tag(event.card,'damage'))); + }, + direct:true, + content:function(){ + 'step 0' + var target=game.findPlayer(current=>current.hasSkill('yichong_'+player.playerid)); + event.target=target; + if(trigger.name=='damage'){ + player.chooseBool(get.prompt('wufei',target),'对'+get.translation(target)+'造成1点伤害').set('choice',get.damageEffect(target,player,player)>0); + } + else{ + player.logSkill('wufei',target); + player.addTempSkill('wufei_effect'); + player.markAuto('wufei_effect',[trigger.card]); + game.log(target,'成为了',trigger.card,'的伤害来源'); + event.finish(); + } + 'step 1' + if(result.bool){ + player.logSkill('wufei',target); + target.damage(); + } + }, + subSkill:{ + effect:{ + charlotte:true, + trigger:{source:'damageBefore'}, + filter:function(event,player){ + if(!event.card) return false; + return player.getStorage('wufei_effect').contains(event.card); + }, + forced:true, + popup:false, + firstDo:true, + content:function(){ + var target=game.findPlayer(current=>current.hasSkill('yichong_'+player.playerid)); + if(!target) delete trigger.source; + else trigger.source=target; + }, + }, + }, + }, + //张嶷 + xinwurong:{ + audio:3, + enable:'phaseUse', + usable:1, + filterTarget:lib.filter.notMe, + content:function(){ + 'step 0' + player.chooseToDuiben(target).set('title','谋弈').set('namelist',[ + '反抗','归顺','镇压','安抚' + ]).set('ai',button=>1+Math.random()); + 'step 1' + if(result.bool){ + if(result.player=='db_def1'){ + target.damage(); + player.draw(); + event.finish(); + } + else{ + var cards=target.getCards('he'); + if(cards.length<2){ + target.skip('phaseDraw'); + target.addTempSkill('xinwurong_skip',{player:'phaseDrawSkipped'}); + event.finish(); + } + else if(cards.length==2) event._result={bool:true,cards:cards}; + else target.chooseCard('怃戎:交给'+get.translation(player)+'两张牌',2,true,'he'); + } + } + else{ + if(result.player=='db_def1'){ + player.gainPlayerCard(target,'he',true); + event.goto(3); + } + else{ + player.damage(); + player.draw(2); + event.finish(); + } + } + 'step 2' + if(result.bool) player.gain(result.cards,target,'giveAuto'); + event.finish(); + 'step 3' + var cards=player.getCards('he'); + if(!cards.length) event.finish(); + else if(cards.length<=2) event._result={bool:true,cards:cards}; + else player.chooseCard('怃戎:交给'+get.translation(target)+'两张牌',2,true,'he'); + 'step 4' + if(result.bool) target.gain(result.cards,player,'giveAuto'); + }, + ai:{ + order:7, + result:{ + player:1, + target:-1, + }, + }, + subSkill:{ + skip:{ + charlotte:true, + mark:true, + intro:{content:'跳过下个摸牌阶段'}, + }, + }, + }, + //孙亮 + xinkuizhu:{ + audio:'nzry_kuizhu', + trigger:{player:'phaseDiscardAfter'}, + filter:function(event,player){ + return player.getHistory('lose',function(evt){ + return evt.type=='discard'&&evt.getParent('phaseDiscard')==event; + }).length; + }, + direct:true, + content:function(){ + 'step 0' + var cards=[]; + player.getHistory('lose',function(evt){ + if(evt.type=='discard'&&evt.getParent('phaseDiscard')==trigger) cards.addArray(evt.cards2); + }); + event.num=cards.length; + event.str1='令至多'+event.num+'名角色摸一张牌'; + event.str2='对任意名体力值之和为'+event.num+'的角色造成1点伤害'; + player.chooseControl('cancel2').set('ai',function(){ + if(game.countPlayer(function(current){return get.attitude(player,current)<0&¤t.hp==event.num})>0&&event.num<=3) return 1; + return 0; + }).set('choiceList',[event.str1,event.str2]).set('prompt','是否发动【溃诛】?'); + 'step 1' + if(result.control=='cancel2') event.finish(); + event.control=[event.str1,event.str2][result.index]; + 'step 2' + var str='请选择〖溃诛〗的目标'; + if(event.bool==false) str='
所选目标体力之和不足'+event.num+',请重选'; + if(event.control==event.str2){ + player.chooseTarget(str,function(card,player,target){ + var targets=ui.selected.targets; + var num=0; + for(var i=0;i=2) player.loseHp(); + } + } + } + }, + }, + xinzhizheng:{ + audio:'nzry_zhizheng', + mod:{ + playerEnabled:function(card,player,target){ + var info=get.info(card); + if(target!=player&&(!info||!info.singleCard||!ui.selected.targets.length)&&player.isPhaseUsing()&&!target.inRange(player)) return false; + }, + }, + trigger:{player:'phaseUseEnd'}, + filter:function(event,player){ + return player.getHistory('useCard',function(evt){ + return evt.getParent('phaseUse')==event; + }).length0); + 'step 1' + if(result.bool){ + player.logSkill('xinlijun',trigger.player); + player.gain(trigger.cards.filterInD(),'gain2'); + player.chooseBool().set('prompt','是否令'+get.translation(trigger.player)+'摸一张牌?').set('choice',get.attitude(player,trigger.player)>0); + } + else event.finish(); + 'step 2' + if(result.bool) trigger.player.draw(); + }, + }, //十常侍 mbdanggu:{ audio:2, @@ -3007,7 +3386,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var cards=player.getExpansions(skill); if(cards.length) player.loseToDiscardpile(cards); }, - marktext:'六', + marktext:'经', intro:{ name:'六经', markcount:'expansion', @@ -3026,11 +3405,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ group:'chengye_gain', subSkill:{ gain:{ + audio:'chengye', trigger:{player:'phaseUseBegin'}, - forced:true, filter:function(event,player){ return player.getExpansions('chengye').length>=6; }, + forced:true, content:function(){ player.gain(player.getExpansions('chengye'),'gain2'); }, @@ -6487,21 +6867,34 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, tianshu:{ audio:2, - enable:'phaseUse', - usable:1, + trigger:{player:'phaseUseBegin'}, filter:function(event,player){ - return player.countCards('he')>0&&!game.hasPlayer(function(current){ + return player.countCards('he')&&!game.hasPlayer(function(current){ return current.countCards('ej','taipingyaoshu'); }); }, - position:'he', - filterCard:true, - filterTarget:true, - check:function(card){ - return 6-get.value(card); - }, + direct:true, content:function(){ 'step 0' + player.chooseCardTarget({ + prompt:get.prompt2('tianshu'), + filterCard:true, + position:'he', + ai1:function(card){ + return 5-get.value(card); + }, + ai2:function(target){ + var player=_status.event.player; + if(get.attitude(player,target)>0&&!target.hasEmptySlot(2)) return 0; + return get.attitude(player,target); + }, + }); + 'step 1' + if(!result.bool){event.finish();return;} + var target=result.targets[0]; + event.target=target; + player.logSkill('tianshu',target); + player.discard(result.cards); if(!lib.inpile.contains('taipingyaoshu')){ lib.inpile.push('taipingyaoshu'); event.card=game.createCard2('taipingyaoshu','heart',3); @@ -6513,20 +6906,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } if(!event.card) event.finish(); else target.gain(event.card,'gain2'); - 'step 1' + 'step 2' if(target.getCards('h').contains(card)&&get.name(card,target)=='taipingyaoshu') target.chooseUseTarget(card,'nopopup',true); }, - ai:{ - order:3, - result:{ - target:function(player,target){ - if(lib.inpile.contains('taipingyaoshu')&&!get.cardPile(function(card){ - return card.name=='taipingyaoshu'; - })) return 0; - return target.getUseValue({name:'taipingyaoshu'}); - }, - }, - }, }, //界伏寿 xinzhuikong:{ @@ -6652,9 +7034,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var source=event.source; if(!source) return false; var cards=source.getEquips(1); - return cards.length&&cards.some(card=>lib.filter.canBeGained(card,player,source)); + return cards.some(card=>lib.filter.canBeGained(card,player,source)); }, - prompt2:function(event){ + prompt2:function(event,player){ var source=event.source; var cards=source.getEquips(1).filter(card=>lib.filter.canBeGained(card,player,source)); return '获得其装备区中的'+get.translation(cards); @@ -7538,6 +7920,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ audio:3, enable:'phaseUse', usable:1, + filter:function(event,player){ + return game.hasPlayer(function(target){ + return lib.skill.beizhu.filterTarget(null,player,target); + }); + }, filterTarget:function(card,player,target){ return target!=player&&target.countCards('h')>0; }, @@ -7551,12 +7938,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ event.cards=cards; event.goto(5); } - else player.discardPlayerCard('he',target,true); + else player.discardPlayerCard('he',target,'visible',true); 'step 2' - player.chooseBool('是否令'+get.translation(target)+'获得一张【杀】?').set('ai',function(){ - var evt=_status.event.getParent(); - return get.attitude(evt.player,evt.target)>0; - }); + player.chooseBool('是否令'+get.translation(target)+'获得一张【杀】?').set('choice',get.attitude(player,target)>0); 'step 3' if(result.bool){ var card=get.cardPile2(function(card){ @@ -7583,6 +7967,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ event.redo(); } }, + ai:{ + order:7, + threaten:1.14+5.14, + result:{ + player:function(player,target){ + var eff=get.effect(target,{name:'guohe_copy2'},player,player); + var cards=target.getCards('h',{name:'sha'}); + if(!cards.length) return eff; + return eff/(cards.length+3); + }, + }, + }, }, beizhu_draw:{ trigger:{player:'damageEnd'}, @@ -13371,8 +13767,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ //伊吹 风子 qiaosi_c6:' ', //仲村 由理 - mobile_sunben:'那个男人', - //孙笨 yangbiao:'手杀杨彪', zhaohan:'昭汉', @@ -13559,7 +13953,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ yufeng2:'御风', yufeng_info:'出牌阶段限一次,你可以表演“御风飞行”。若表演失败,则你摸X张牌。若表演成功,则你可以选择至多X名其他角色获得“御风”效果,然后摸X-Y张牌(准备阶段开始时,你进行判定。若结果为:红色,你跳过摸牌阶段;黑色,你跳过出牌阶段和弃牌阶段。X为你的得分。Y为你选择的角色数)。', tianshu:'天书', - tianshu_info:'出牌阶段限一次,若场上没有【太平要术】,则你可以弃置一张牌并选择一名角色。该角色获得并使用【太平要术】。', + tianshu_info:'出牌阶段开始时,若场上没有【太平要术】,则你可以弃置一张牌并选择一名角色。该角色获得并使用【太平要术】。', re_jiangwei:'手杀姜维', retiaoxin:'挑衅', retiaoxin_info:'出牌阶段限一次,你可以指定一名有牌的其他角色,该角色需对你使用一张【杀】,否则你弃置其一张牌。', @@ -13816,10 +14210,30 @@ game.import('character',function(lib,game,ui,get,ai,_status){ scsanruo_info:'你可以将一张♥牌当【桃】、♦牌当火【杀】、♣牌当【闪】、♠牌当【无懈可击】使用。当你以此法使用或打出【杀】或【闪】时,你可以获得对方的一张牌;当你以此法使用【桃】时,你可以获得一名其他角色的一张牌;当你以此法使用【无懈可击】时,你可以获得此牌响应的普通锦囊牌的使用者的一张牌。', scsmiaoyu:'妙语', scsmiaoyu_info:'你可以将至多两张相同花色的牌按照以下规则使用或打出:♦牌当作火【杀】,♥牌当作【桃】,♣牌当作【闪】,♠牌当作【无懈可击】。若你以此法使用了两张红色牌,则此牌回复值或伤害值+1。若你以此法使用了两张黑色牌,则你弃置当前回合角色一张牌。', - + re_xiaoqiao:'手杀小乔', + xin_sunliang:'手杀孙亮', + xinkuizhu:'溃诛', + xinkuizhu_info:'弃牌阶段结束后,你可以选择一项:1.令至多X名角色各摸一张牌。2.对任意名体力值之和为X的角色造成1点伤害,若你以此法选择的角色数不小于2,你失去1点体力。(X为你此阶段弃置的牌数)', + xinzhizheng:'掣政', + xinzhizheng_info:'锁定技,你的出牌阶段内,攻击范围内不包含你的其他角色不能成为你使用牌的目标。出牌阶段结束时,若你本阶段内使用的牌数小于这些角色的数量,则你弃置其中一名角色的一张牌。', + xinlijun:'立军', + xinlijun_info:'主公技,其他吴势力角色于其回合内使用【杀】结算完毕后,其可以将此【杀】对应的实体牌交给你,然后你可以令其摸一张牌。', + xin_zhangyi:'手杀张嶷', + xinwurong:'怃戎', + xinwurong_info:'出牌阶段限一次,你可以与一名其他角色进行谋弈:
  • 若你选择“镇压”且其选择“反抗”,你对其造成1点伤害,然后你摸一张牌。
  • 若你选择“安抚”且其选择“归顺”,其须交给你两张牌(若其手牌数不足两张,则改为令其跳过其下个摸牌阶段)。
  • 若你选择“镇压”且其选择“归顺”,你获得其一张牌,然后你交给其两张牌。
  • 若你选择“安抚”且其选择“反抗”,你受到1点伤害,然后你摸两张牌。', + xin_guozhao:'手杀郭照', + yichong:'易宠', + yichong_info:'①准备阶段,你可以选择一名其他角色并选择一个花色,然后你获得其所有此花色的牌,移除场上的所有“雀”标记,令其获得“雀”标记直到你的下个回合开始。②拥有“雀”标记的角色获得你最后一次发动〖易宠①〗选择的花色的牌后,你获得这些牌(你至多通过每个“雀”获得五张牌)。', + wufei:'诬诽', + wufei_info:'若场上存在拥有“雀”标记的角色A,则:①当你使用【杀】或伤害类锦囊牌指定第一个目标后,你令A成为此牌伤害来源。②当你受到伤害后,若A的体力值大于1且A的体力值大于你,则你可以对A造成1点伤害。', mobile_standard:'手杀异构·标准包', - mobile_shenhua:'手杀异构·神话再临', + mobile_shenhua_feng:'手杀异构·其疾如风', + mobile_shenhua_huo:'手杀异构·侵掠如火', + mobile_shenhua_lin:'手杀异构·其徐如林', + mobile_shenhua_shan:'手杀异构·不动如山', + mobile_shenhua_yin:'手杀异构·难知如阴', + mobile_shenhua_lei:'手杀异构·动如雷霆', mobile_yijiang1:'手杀异构·将1', mobile_yijiang2:'手杀异构·将2', mobile_yijiang3:'手杀异构·将3', diff --git a/character/offline.js b/character/offline.js index 071d8a5462..14311104ae 100644 --- a/character/offline.js +++ b/character/offline.js @@ -3647,12 +3647,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ result:{player:1}, effect:{ target:function(card,player,target){ - if(card&&get.type(card)=='equip'&&_status.event.skill=='_yongjian_zengyu') return 0; + if(card&&get.type(card)=='equip'&&_status.event.skill=='_gifting') return 0; }, }, }, mod:{ - cardZengyuable:function(card,player){ + cardGiftable:function(card,player){ return get.type(card)=='equip'; } } @@ -3786,19 +3786,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, //群曹操 yjxiandao:{ - trigger:{player:'_yongjian_zengyuEnd'}, + trigger:{player:'giftAccepted'}, usable:1, forced:true, locked:false, - filter:function(event,player){ - return !event._zengyu_denied&&event.target.isIn(); - }, + filter:(event,player)=>event.target!=player&&event.target.isIn(), logTarget:'target', content:function(){ 'step 0' event.target=trigger.target; - event.card=trigger.cards[0]; - event.target.markAuto('yjxiandao',[get.suit(event.card,false)]) + event.card=trigger.card; + event.target.markAuto('yjxiandao_block',[get.suit(event.card,false)]); event.target.addTempSkill('yjxiandao_block'); 'step 1' var type=get.type(card,false); @@ -3859,14 +3857,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }); 'step 2' if(result.bool){ - player.line(result.targets[0],'green'); - var next=game.createEvent('_yongjian_zengyu'); - next.player=player; - next.target=result.targets[0]; - next.cards=result.cards; - next.setContent(lib.skill._yongjian_zengyu.content); + var target=result.targets[0]; + player.line(target,'green'); + player.gift(result.cards,target); } - }, + } }, yjyibing:{ trigger:{ @@ -3875,7 +3870,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, direct:true, filter:function(event,player){ - if(event.getParent().name=='_yongjian_zengyu') return false; + if(event.getParent().name=='gift') return false; if(event.getParent('yjyibing').player==player) return false; var evt=event.getParent('phaseDraw'),hs=player.getCards('h'),cards=event.getg(player); return cards.length>0&&(!evt||evt.player!=player)&&cards.filter(function(card){ @@ -6403,11 +6398,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ //用间 yj_caocao:'SP曹操', yjxiandao:'献刀', - yjxiandao_info:'每回合限一次。当你对其他角色发动〖赠予〗后,你令其不能使用或打出与本次赠予移动的牌A花色相同的牌直到回合结束。然后若牌A:为锦囊牌,你摸两张牌。为装备牌,你获得其一张不为A的牌。为武器牌,你对其造成1点伤害。', + yjxiandao_info:'每回合限一次。当你赠予其他角色一张牌后,你令其不能使用或打出与本次赠予移动的牌A花色相同的牌直到回合结束。然后若牌A:为锦囊牌,你摸两张牌。为装备牌,你获得其一张不为A的牌。为武器牌,你对其造成1点伤害。', yjsancai:'散财', - yjsancai_info:'出牌阶段限一次,你可以展示所有手牌。若这些牌的类别均相同,则你可以发动一次〖赠予〗(可以选择任意手牌)。', + yjsancai_info:'出牌阶段限一次,你可以展示所有手牌。若这些牌的类别均相同,则你可以赠予一名其他角色一张手牌。', yjyibing:'义兵', - yjyibing_info:'当你不因〖赠予〗且不因〖义兵〗的嵌套结算而于摸牌阶段外获得牌时,你可以将此次获得的所有牌当做【杀】使用(无距离限制且不计入使用次数)。', + yjyibing_info:'当你不因赠予且不因〖义兵〗的嵌套结算而于摸牌阶段外获得牌时,你可以将此次获得的所有牌当做【杀】使用(无距离限制且不计入使用次数)。', yj_caohong:'用间曹洪', yj_caohong_ab:'曹洪', yjlifeng:'厉锋', diff --git a/character/old.js b/character/old.js index 2ae282792c..4baccbd77b 100755 --- a/character/old.js +++ b/character/old.js @@ -7,7 +7,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ characterSort:{ old:{ old_standard:['ol_yuanshu'], - old_shenhua:["yuji","zhangjiao","old_zhugezhan","old_guanqiujian","xiahouyuan","weiyan","xiaoqiao","pangde","xuhuang",'junk_sunquan',"huangzhong","new_caoren",'old_chendao'], + old_shenhua:["yuji","zhangjiao","old_zhugezhan","old_guanqiujian","xiahouyuan","weiyan","old_xiaoqiao","pangde","xuhuang",'junk_sunquan',"huangzhong","new_caoren",'old_chendao'], old_refresh:["old_zhangfei","old_huatuo","old_zhaoyun","ol_huaxiong",'old_re_lidian'], old_yijiang1:["masu","xushu","xin_yujin","old_xusheng","old_lingtong","fazheng",'old_gaoshun'], old_yijiang2:["old_zhonghui","madai",'old_handang','old_liubiao','oldre_liubiao','old_guanzhang'], @@ -45,7 +45,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ pangde:['male','qun',4,['mashu','mengjin']], ol_huaxiong:["male","qun",6,["new_reyaowu"]], old_wangyun:['male','qun',4,['wylianji','moucheng'],['clan:太原王氏']], - xiaoqiao:['female','wu',3,['tianxiang','hongyan']], + old_xiaoqiao:['female','wu',3,['tianxiang','hongyan']], weiyan:['male','shu',4,['kuanggu']], xiahouyuan:['male','wei',4,['shensu']], old_huangfusong:['male','qun',4,['fenyue']], @@ -61,7 +61,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ jsp_caoren:['male','wei',4,['kuiwei','yanzheng']], old_caochun:['male','wei',4,['shanjia']], masu:['male','shu',3,['xinzhan','huilei']], - xushu:['male','shu',3,['xswuyan','jujian']], + xushu:['male','shu',3,['xswuyan','jujian'],['border:wei']], liru:['male','qun',3,['juece','mieji','fencheng']], xin_yujin:['male','wei',4,['jieyue']], //lusu:['male','wu',3,['haoshi','dimeng']], @@ -971,6 +971,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ old_zhaoyun:'新杀赵云', old_zhaoyun_ab:'赵云', ol_huaxiong:'旧华雄', + old_xiaoqiao:'旧小乔', old_guhuo:"蛊惑", old_guhuo_info:"你可以扣置一张手牌当做一张基本牌或普通锦囊牌使用或打出,体力值不为0的其他角色依次选择是否质疑。然后,若有质疑的角色,你展示此牌:若为假,此牌作废,这些角色摸一张牌;若为真,这些角色失去1点体力,且若此牌不为♥,此牌作废。", diff --git a/character/sb.js b/character/sb.js index c50977cb8a..4c091fa843 100644 --- a/character/sb.js +++ b/character/sb.js @@ -5,13 +5,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ name:'sb', connect:true, character:{ + sb_zhanghe:['male','wei',4,['sbqiaobian'],['unseen']], sb_yujin:['male','wei',4,['sbxiayuan','sbjieyue']], sb_huaxiong:['male','qun','3/4/1',['new_reyaowu','sbyangwei']], liucheng:['female','qun',3,['splveying','spyingwu']], sp_yangwan:['female','qun',3,['spmingxuan','spxianchou']], sb_huangzhong:['male','shu',4,['sbliegong']], sb_lvmeng:['male','wu',4,['sbkeji','sbdujiang']], - sb_sunshangxiang:['female','shu',4,['sbjieyin','sbliangzhu','sbxiaoji']], + sb_sunshangxiang:['female','shu',4,['sbjieyin','sbliangzhu','sbxiaoji'],['border:wu']], sb_sunquan:['male','wu',4,['sbzhiheng','sbtongye','sbjiuyuan'],['zhu']], sb_huanggai:['male','wu',4,['sbkurou','sbzhaxiang']], sb_zhouyu:['male','wu',3,['sbyingzi','sbfanjian']], @@ -48,6 +49,103 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, skill:{ + //张郃 + sbqiaobian:{ + audio:2, + trigger:{player:['phaseJudgeBefore','phaseDrawBefore','phaseUseBefore']}, + filter:function(event,player){ + if(event.name=='phaseJudge') return player.countCards('j'); + return event.name!='phaseUse'||player.countCards('h')>6; + }, + usable:1, + direct:true, + content:function(){ + 'step 0' + switch(trigger.name){ + case 'phaseJudge': + player.chooseTarget(get.prompt('sbqiaobian'),'失去1点体力并跳过判定阶段,将判定区里的牌移动给一名其他角色',lib.filter.notMe).set('ai',function(target){ + var player=_status.event.player; + if(player.hp+player.countCards('h',function(card){ + var mod2=game.checkMod(card,player,'unchanged','cardEnabled2',player); + if(mod2!='unchanged') return mod2; + var mod=game.checkMod(card,player,player,'unchanged','cardSavable',player); + if(mod!='unchanged') return mod; + var savable=get.info(card).savable; + if(typeof savable=='function') savable=savable(card,player,player); + return savable; + })<=1) return 0; + var eff=0; + for(var card of player.getCards('j')){ + var cardx; + if(card.viewAs) cardx=get.autoViewAs({name:card.viewAs},[card]); + else cardx=card; + if(target.canAddJudge(cardx)) eff+=get.effect(target,cardx,player,player); + else eff-=get.attitude(player,target)/114514; + } + return eff; + }).setHiddenSkill('sbqiaobian'); + break; + case 'phaseDraw': + player.chooseBool(get.prompt('sbqiaobian'),'跳过摸牌阶段,于下个准备阶段摸两张牌并回复1点体力').setHiddenSkill('sbqiaobian'); + break; + case 'phaseUse': + var num=(player.countCards('h')-6); + player.chooseToDiscard(get.prompt('sbqiaobian'),num,'弃置'+get.cnNumber(num)+'张手牌并跳过出牌阶段和弃牌阶段,然后移动场上的一张牌').set('ai',function(card){ + var player=_status.event.player; + if(!player.canMoveCard(true)||player.countCards('hs',card=>player.hasValueTarget(card))>=9) return 0; + return 7-get.value(card); + }).setHiddenSkill('sbqiaobian').logSkill='sbqiaobian'; + break; + } + 'step 1' + if(result.bool){ + trigger.cancel(); + switch(trigger.name){ + case 'phaseJudge': + var target=result.targets[0]; + player.logSkill('sbqiaobian',target); + player.loseHp(); + game.log(player,'跳过了判定阶段'); + for(var card of player.getCards('j')){ + if(target.canAddJudge(card)){ + player.$give(card,target,false); + if(card.viewAs) target.addJudge({name:card.viewAs},[card]); + else target.addJudge(card); + } + else player.discard(card); + } + break; + case 'phaseDraw': + player.logSkill('sbqiaobian'); + game.log(player,'跳过了摸牌阶段'); + player.addSkill('sbqiaobian_draw'); + break; + case 'phaseUse': + player.skip('phaseDiscard'); + game.log(player,'跳过了出牌阶段'); + game.log(player,'跳过了弃牌阶段'); + player.moveCard(); + break; + } + } + else player.storage.counttrigger.sbqiaobian--; + }, + subSkill:{ + draw:{ + charlotte:true, + mark:true, + intro:{content:'准备阶段摸两张牌并回复1点体力'}, + audio:'sbqiaobian', + trigger:{player:'phaseZhunbeiBegin'}, + forced:true, + content:function(){ + player.removeSkill('sbqiaobian_draw'); + player.draw(2); + player.recover(); + }, + }, + }, + }, //萌货 sbhuoshou:{ audio:2, @@ -467,6 +565,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, sbzhiba:{ + init:function(player){ + if(player.hasZhuSkill('sbzhiba')) player.markSkill('sbzhiba'); + }, audio:2, trigger:{player:'dying'}, filter:function(event,player){ @@ -475,6 +576,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, zhuSkill:true, limited:true, + mark:false, skillAnimation:true, animationColor:'wood', content:function(){ @@ -1603,7 +1705,19 @@ game.import('character',function(lib,game,ui,get,ai,_status){ lose:false, delay:false, filter:function(event,player){ - return player.countMark('sbrende')<2||player.hasSkill('sbrende_used'); + if(player.countMark('sbrende')<2||player.hasSkill('sbrende_used')) return true; + for(var name of lib.inpile){ + if(get.type(name)!='basic') continue; + var card={name:name,isCard:true}; + if(event.filterCard(card,player,event)) return false; + if(name=='sha'){ + for(var nature of lib.inpile_nature){ + card.nature=nature; + if(event.filterCard(card,player,event)) return false; + } + } + } + return true; }, filterTarget:function(card,player,target){ if(player.getStorage('sbrende_given').contains(target)) return false; @@ -3496,7 +3610,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ onremove:true, content:function(){ 'step 0' - player.chooseControl('变化','不变').set('prompt','统业:猜测场上装备数是否于你下回合准备阶段前发生变化').set('ai',()=>(game.countPlayer()<=4?Math.random():1)<0.4); + player.chooseControl('变化','不变').set('prompt','统业:猜测场上装备数是否于你下回合准备阶段前发生变化').set('ai',()=>Number((game.countPlayer()<=4?Math.random():1)<0.4)); 'step 1' if(result.control=='变化'){ player.addSkill('sbtongye_change',1); @@ -4643,6 +4757,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sbhuoshou_info:'锁定技。①【南蛮入侵】对你无效。②当其他角色使用【南蛮入侵】指定第一个目标后,你代替其成为此牌的伤害来源。③出牌阶段开始时,你随机获得弃牌堆中的一张【南蛮入侵】。④出牌阶段,若你于此阶段使用过【南蛮入侵】,你不能使用【南蛮入侵】。', sbzaiqi:'再起', sbzaiqi_info:'蓄力技(1/7)。①弃牌阶段结束时,你可以消耗任意点蓄力值并选择等量名角色,然后令这些角色选择一项:1.令你摸一张牌;2.弃置一张牌,然后你回复1点体力。②每回合限一次。当你造成伤害后,你获得1点蓄力值。', + sb_zhanghe:'谋张郃', + sbqiaobian:'巧变', + sbqiaobian_info:'每回合限一次。①你可以失去1点体力并跳过判定阶段,将判定区的所有牌移动给一名其他角色(无法置入其判定区的牌改为弃置之)。②你可以跳过摸牌阶段,于下个准备阶段摸两张牌并回复1点体力。③你可以将手牌数弃置至六张并跳过出牌阶段和弃牌阶段,然后移动场上的一张牌。', sb_zhi:'谋攻篇·知', sb_shi:'谋攻篇·识', diff --git a/character/shenhua.js b/character/shenhua.js index da831624d0..09c3962474 100755 --- a/character/shenhua.js +++ b/character/shenhua.js @@ -5,7 +5,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ connect:true, characterSort:{ shenhua:{ - shenhua_feng:["sp_zhangjiao","re_yuji","old_zhoutai","old_caoren","re_xiahouyuan","re_xiaoqiao","re_huangzhong","re_weiyan"], + shenhua_feng:["sp_zhangjiao","re_yuji","old_zhoutai","old_caoren","re_xiahouyuan","xiaoqiao","re_huangzhong","re_weiyan"], shenhua_huo:['dianwei','xunyu','pangtong','sp_zhugeliang','taishici','yanwen','re_yuanshao','re_pangde'], shenhua_lin:['caopi','re_xuhuang','menghuo','zhurong','re_lusu','sunjian','dongzhuo','jiaxu'], shenhua_shan:['dengai','zhanghe','liushan','jiangwei','zhangzhang','sunce','caiwenji','zuoci'], @@ -21,7 +21,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ re_pangde:['male','qun',4,['mashu','jianchu']], re_xiahouyuan:['male','wei',4,['xinshensu']], re_weiyan:['male','shu',4,['xinkuanggu','qimou']], - re_xiaoqiao:['female','wu',3,['retianxiang','xinhongyan']], + xiaoqiao:['female','wu',3,['retianxiang','hongyan']], sp_zhangjiao:['male','qun',3,['releiji','guidao','huangtian'],['zhu']], re_yuji:["male","qun",3,["xinfu_guhuo"]], // yuji:['male','qun',3,['guhuo']], @@ -1014,19 +1014,21 @@ game.import('character',function(lib,game,ui,get,ai,_status){ })>1) return 'equip5'; }); 'step 1' - if(result.control=='equip1'){ - player.addTempSkill('drlt_jueyan1',{player:'phaseAfter'}); - }; - if(result.control=='equip2'){ - player.draw(3); - player.addTempSkill('drlt_jueyan3',{player:'phaseAfter'}); - }; - if(result.control=='equip6'){ - player.addTempSkill('drlt_jueyan2',{player:'phaseAfter'}); - }; - if(result.control=='equip5'){ - player.addTempSkill('rejizhi',{player:'phaseAfter'}); - }; + switch(result.control){ + case 'equip1': + player.addTempSkill('drlt_jueyan1',{player:'phaseAfter'}); + break; + case 'equip2': + player.draw(3); + player.addTempSkill('drlt_jueyan3',{player:'phaseAfter'}); + break; + case 'equip3_4': + player.addTempSkill('drlt_jueyan2',{player:'phaseAfter'}); + break; + case 'equip5': + player.addTempSkill('rejizhi',{player:'phaseAfter'}); + break; + } }, ai:{ order:13, @@ -7023,7 +7025,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return true; } else if(event.name=='gain'){ - if(event.giver||event.getParent().name=='_yongjian_zengyu') return false; + if(event.giver||event.getParent().name=='gift') return false; var cards=event.getg(event.player); if(!cards.length) return false; return game.hasPlayer(function(current){ @@ -7700,6 +7702,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ol_lusu:['ol_lusu','re_lusu'], zhanghe:['re_zhanghe','zhanghe'], yl_luzhi:['yl_luzhi','tw_yl_luzhi'], + sunliang:['sunliang','xin_sunliang'], }, translate:{ re_yuanshao:'袁绍', @@ -8005,12 +8008,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ re_xiahouyuan:'夏侯渊', re_huangzhong:'黄忠', re_weiyan:'魏延', - re_xiaoqiao:'小乔', gz_xiahouyuan:'夏侯渊', gz_huangzhong:'黄忠', gz_weiyan:'魏延', - gz_xiaoqiao:'小乔', gz_xuhuang:'徐晃', gz_pangde:'庞德', gz_caoren:'曹仁', @@ -8025,7 +8026,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ huangzhong:'旧黄忠', sp_zhangjiao:'张角', weiyan:'旧魏延', - xiaoqiao:'旧小乔', + xiaoqiao:'小乔', zhoutai:'界周泰', zhangjiao:'旧张角', //yuji:'于吉', diff --git a/character/shiji.js b/character/shiji.js index 17f0102f47..ce5614617d 100644 --- a/character/shiji.js +++ b/character/shiji.js @@ -1118,7 +1118,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var target=trigger.player,card=result.cards[0],suit=get.suit(card,player); if(!lib.suit.contains(suit)||(!target||!target.isIn())&&suit!='heart') return; game.broadcastAll(function(suit){ - if(lib.config.background_speak) game.playAudio('skill','spfangzong'+(4-lib.suit.indexOf(suit))); + if(lib.config.background_speak) game.playAudio('skill','spxizhan'+(4-lib.suit.indexOf(suit))); },suit); switch(suit){ case 'spade': @@ -4058,22 +4058,38 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ 'step 0' var list=get.zhinangs(); - player.chooseButton(['是否发动【生息】获得一张智囊?',[list,'vcard']]).set('ai',function(card){ - return (Math.random()+0.5)*get.value({name:card.link[2]},_status.event.player) + player.chooseButton([ + '###'+get.prompt('mjshengxi')+'###获得一张智囊或摸一张牌', + [list,'vcard'], + [['摸一张牌','取消'],'tdnodes'], + ],true).set('ai',function(card){ + if(card.link[2]){ + if(!get.cardPile2(function(cardx){ + return cardx.name==card.link[2]; + })) return 0; + return (Math.random()+1.5)*get.value({name:card.link[2]},_status.event.player); + } + if(card.link=='摸一张牌') return 1; + return 0; }); 'step 1' - if(result.bool){ + if(result.bool&&result.links[0]!='取消'){ player.logSkill('mjshengxi'); - var card=get.cardPile2(function(card){ - return card.name==result.links[0][2]; - }); - if(card) player.gain(card,'gain2'); + if(result.links[0]=='摸一张牌') player.draw(); + else{ + var card=get.cardPile2(function(card){ + return card.name==result.links[0][2]; + }); + if(card) player.gain(card,'gain2'); + } } }, group:'mjshengxi_zhunbei', subfrequent:['zhunbei'], subSkill:{ zhunbei:{ + audio:'shengxi', + audioname:['feiyi'], trigger:{player:'phaseZhunbeiBegin'}, frequent:true, prompt2:'从游戏外或牌堆中获得一张【调剂盐梅】', @@ -4118,7 +4134,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }); 'step 1' if(result.bool){ - event.card=result.links[0]; + var card=result.links[0]; + event.card=card; player.chooseTarget('将'+get.translation(card)+'交给一名其他角色并摸一张牌',lib.filter.notMe,true).set('ai',function(target){ var evt=_status.event.getParent(); return get.attitude(evt.player,target)*get.value(evt.card,target)*(target.hasSkillTag('nogain')?0.1:1); @@ -5382,20 +5399,34 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, fyjianyu:{ + init:function(player){ + if(!lib.skill['fyjianyu_'+player.playerid]){ + lib.skill['fyjianyu_'+player.playerid]={ + marktext:'喻', + intro:{ + markcount:()=>1, + content:'指定另一名有“喻”的角色为目标时,其摸一张牌', + }, + }; + lib.translate['fyjianyu_'+player.playerid]='谏喻'; + lib.translate['fyjianyu_'+player.playerid+'_bg']='喻'; + } + }, + audio:2, enable:'phaseUse', - usable:1, filter:function(event,player){ - return !player.hasSkill('fyjianyu2')&&game.countPlayer(function(current){ - return !current.hasMark('fyjianyux'); + return game.countPlayer(function(current){ + return !current.hasMark('fyjianyu_'+player.playerid); })>1; }, + round:1, filterTarget:function(card,player,target){ - return !target.hasMark('fyjianyux'); + return !target.hasMark('fyjianyu_'+player.playerid); }, selectTarget:2, content:function(){ - player.addTempSkill('fyjianyux',{player:'phaseBegin'}); - target.addMark('fyjianyux',1); + player.addTempSkill('fyjianyu_draw',{player:'phaseBegin'}); + target.addMark('fyjianyu_'+player.playerid,1); }, ai:{ order:0.1, @@ -5411,30 +5442,27 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, }, - }, - fyjianyux:{ - trigger:{global:'useCardToPlayer'}, - forced:true, - charlotte:true, - filter:function(event,player){ - return event.player!=event.target&&event.player.hasMark('fyjianyux')&& - event.target.hasMark('fyjianyux')&&event.target.isIn(); - }, - logTarget:'target', - content:function(){ - trigger.target.draw(); - }, - onremove:function(){ - game.countPlayer(function(current){ - var num=current.countMark('fyjianyux'); - if(num) current.removeMark('fyjianyux'); - }); - }, - intro:{ - content:'mark', + subSkill:{ + draw:{ + charlotte:true, + trigger:{global:'useCardToPlayer'}, + filter:function(event,player){ + return event.player!=event.target&&event.player.hasMark('fyjianyu_'+player.playerid)&&event.target.hasMark('fyjianyu_'+player.playerid)&&event.target.isIn(); + }, + forced:true, + logTarget:'target', + content:function(){ + trigger.target.draw(); + }, + onremove:function(player){ + game.countPlayer(function(current){ + var num=current.countMark('fyjianyu_'+player.playerid); + if(num) current.removeMark('fyjianyu_'+player.playerid); + }); + }, + }, }, }, - fyjianyu2:{}, spwanwei:{ audio:2, enable:'chooseToUse', @@ -6120,7 +6148,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } return true; }, - chongzhu:true, + recastable:true, selectTarget:2, postAi:()=>true, contentBefore:function(){ @@ -6339,9 +6367,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ reshengxi_info:'结束阶段,若你于本回合内未造成过伤害,则你可摸两张牌。', fyjianyu:'谏喻', fyjianyu_info:'每轮限一次。出牌阶段,你可选择两名角色,令这些角色获得“喻”直到你的下回合开始。当一名有“喻”的角色A使用牌指定另一名有“喻”的角色B为目标时,你令B摸一张牌。', - fyjianyux:'谏喻', mjshengxi:'生息', - mjshengxi_info:'准备阶段,你可以获得一张【调剂盐梅】;结束阶段,若你本回合使用过牌且未造成伤害,则你可以获得一张智囊。', + mjshengxi_info:'准备阶段,你可以获得一张【调剂盐梅】;结束阶段,若你本回合使用过牌且未造成伤害,则你可以获得一张智囊或摸一张牌。', mjkuanji:'宽济', mjkuanji_info:'每回合限一次。当你因弃置而失去牌后,你可令一名其他角色获得其中的一张牌,然后你摸一张牌。', tiaojiyanmei:'调剂盐梅', @@ -6522,7 +6549,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ spjungong_info:'出牌阶段,你可失去X+1点体力或弃置X+1张牌,视为对一名其他角色使用【杀】(不计入次数和距离限制,X为你本回合内发动过〖峻攻〗的次数)。若你因此【杀】造成了伤害,则你令此技能失效直到回合结束。', spdengli:'等力', spdengli_info:'当你使用【杀】指定目标后,或成为【杀】的目标后,若使用者和目标的体力值相等,则你摸一张牌。', - sp_huaman:'手杀花蔓', + sp_huaman:'手杀花鬘', spxiangzhen:'象阵', spxiangzhen_info:'锁定技。①【南蛮入侵】对你无效。②当有角色使用的【南蛮入侵】结算结束后,若有角色因此牌受到过伤害,则你和使用者各摸一张牌。', spfangzong:'芳踪', diff --git a/character/sp.js b/character/sp.js index c8e91f0bd6..539c4f4c02 100755 --- a/character/sp.js +++ b/character/sp.js @@ -7,15 +7,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sp:{ sp_tianji:["sunhao","liuxie","caoang","hetaihou","sunluyu",'ol_wangrong',"zuofen","ganfuren","ol_bianfuren","qinghegongzhu","tengfanglan","ruiji",'caoxiancaohua'], sp_sibi:["yangxiu","chenlin","chengyu","shixie","fuwan","wangyun","zhugejin","simalang","maliang","buzhi","dongyun","kanze","sunqian","xizhicai","sunshao",'duxi',"jianggan",'ol_dengzhi','ol_yangyi','ol_dongzhao','ol_chendeng','jin_yanghu','wangyan','xiahouxuan','quhuang','zhanghua','wangguan','sunhong'], - sp_tianzhu:["wutugu","yanbaihu","shamoke","panfeng","zhugedan",'huangzu','gaogan',"tadun","fanjiangzhangda","ahuinan","dongtuna"], + sp_tianzhu:["wutugu","yanbaihu","shamoke","panfeng","zhugedan",'huangzu','gaogan',"tadun","fanjiangzhangda","ahuinan","dongtuna",'ol_wenqin'], sp_nvshi:["lingju","guanyinping","zhangxingcai","mayunlu","dongbai","zhaoxiang",'ol_zhangchangpu','ol_xinxianying',"daxiaoqiao","jin_guohuai"], sp_shaowei:["simahui","zhangbao","zhanglu","zhugeguo","xujing","zhangling",'huangchengyan','zhangzhi','lushi'], - sp_huben:["caohong","xiahouba","zhugeke","zumao","wenpin","litong","mazhong","heqi","quyi","luzhi","zangba","yuejin","dingfeng","wuyan","ol_zhuling","tianyu","huojun",'zhaoyǎn','dengzhong','ol_furong','macheng','ol_zhangyì','ol_zhujun','maxiumatie','luoxian','ol_wenqin'], + sp_huben:['duanjiong','ol_mengda',"caohong","xiahouba","zhugeke","zumao","wenpin","litong","mazhong","heqi","quyi","luzhi","zangba","yuejin","dingfeng","wuyan","ol_zhuling","tianyu","huojun",'zhaoyǎn','dengzhong','ol_furong','macheng','ol_zhangyì','ol_zhujun','maxiumatie','luoxian','ol_huban','haopu'], sp_liesi:['mizhu','weizi','ol_liuba','zhangshiping'], - sp_default:["sp_diaochan","sp_zhaoyun","sp_sunshangxiang","sp_caoren","sp_jiangwei","sp_machao","sp_caiwenji","jsp_guanyu","jsp_huangyueying","sp_pangde","sp_jiaxu","yuanshu",'sp_zhangliao','sp_ol_zhanghe','sp_menghuo','ol_puyuan','ol_wenqin'], - sp_waitforsort:['ol_huban','ol_mengda','haopu'], + sp_default:["sp_diaochan","sp_zhaoyun","sp_sunshangxiang","sp_caoren","sp_jiangwei","sp_machao","sp_caiwenji","jsp_guanyu","jsp_huangyueying","sp_pangde","sp_jiaxu","yuanshu",'sp_zhangliao','sp_ol_zhanghe','sp_menghuo'], + sp_waitforsort:[], sp_qifu:["caoying",'panshu',"caochun","yuantanyuanshang",'caoshuang','wolongfengchu','guansuo','baosanniang','fengfangnv','jin_zhouchu'], - sp_wanglang:['ol_wanglang'], + sp_wanglang:['ol_wanglang','ol_puyuan','ol_zhouqun'], sp_zhongdan:["cuiyan","huangfusong"], sp_guozhan2:["sp_dongzhuo","liqueguosi","zhangren"], //sp_single:["niujin"], @@ -28,6 +28,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, character:{ + duanjiong:['male','qun',4,['olsaogu']], ol_zhouqun:['male','shu',4,['oltianhou','olchenshuo']], ol_wenqin:['male','wei',4,['olguangao','olhuiqi']], haopu:['male','shu',4,['olzhenying']], @@ -191,6 +192,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ //kaisa:["male","western",4,["zhengfu"]], }, characterIntro:{ + duanjiong:'段颎(?-179年),字纪明,武威姑臧(今甘肃省武威市)人。东汉名将,西域都护段会宗从曾孙,与皇甫规(字威明)、张奂(字然明)并称“凉州三明”。段颎少时学习骑射,有文武智略,最初被举为孝廉,为宪陵园丞、阳陵令,有治理之才。汉桓帝时入军旅,先破鲜卑,后讨平东郭窦、公孙举起事,以功封列侯。延熹二年(159年)起戍边征战十余年,百战羌人,至永康元年(167年)平定西羌,建宁二年(169年)平定东羌,前后斩东西羌六万余级。累功封新丰县侯。建宁三年(170年),段颎被征入朝,历任侍中、执金吾、河南尹、司隶校尉等职,他党附宦官、捕杀太学生,因而得保富贵,两度出任太尉。光和二年(179年),权宦王甫罪行被揭发,段颎受牵连下狱,其后在狱中饮鸩而死。', haopu:'郝普,字子太,义阳(治所在今湖北枣阳东南)人。刘备入川后,郝普为零陵太守。建安二十年(215年),吴将吕蒙进攻荆州三郡,唯有郝普坚守待援。但援兵久久不至,其挚友邓玄之又被吕蒙所骗,郝普也因此上当,投降吴国。湘水划界后,郝普回归刘备。建安二十四年(219年),吕蒙再次袭击荆州,击败关羽,郝普再次投降,最终归顺吴国并官至廷尉。郝普与隐蕃亲善,隐蕃蓄谋叛变事情败露,他受到牵连,因此自杀。在刘备集团的5个荆州郡守中,郝普是唯一一个抵抗过东吴的荆州郡守。', ol_zhanghe:'字儁乂,河间鄚人。三国时期魏国名将。官渡之战时,本为袁绍部将的张郃投降了曹操,并在曹操帐下多立功勋,于曹魏建立后加封为征西车骑将军。诸葛亮六出祁山之间,张郃多次抵御蜀军的进攻,于公元231年在木门道被诸葛亮设伏射死。后谥曰壮侯。为曹魏“五子良将”之一。', zhangshiping:'张世平是东汉末期的中山商人,曾与苏双同路,资助刘备组织武装、建立政权。于《三国演义》第一回出场,刘关张桃园三结义时资助刘备良马五十匹,金银五百两,镔铁一千斤。刘备所使用的“双股剑”、关羽所使用的“青龙偃月刀(又名‘冷艳锯’)”、张飞所使用的“丈八点钢矛(又名‘丈八蛇矛’)”皆由这一千斤上好镔铁打造而成。', @@ -688,6 +690,235 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, skill:{ + //段颎 + olsaogu:{ + audio:2, + zhuanhuanji:true, + mark:true, + marktext:'☯', + intro:{ + content:function(storage){ + if(storage) return '转换技。①出牌阶段,你可以摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色摸一张牌。'; + return '转换技。①出牌阶段,你可以弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】。②结束阶段,你可以弃置一张牌,令一名其他角色弃置两张牌,然后其使用弃置的【杀】。'; + }, + }, + onChooseToUse:function(event){ + if(!game.online&&!event.olsaogu){ + var list=[],player=event.player; + var evtx=event.getParent('phaseUse'); + player.getHistory('lose',evt=>{ + if(evt.type=='discard'&&evt.getParent('phaseUse')==evtx) list.addArray(evt.cards2); + }); + event.set('olsaogu',list); + } + }, + enable:'phaseUse', + filter:function(event,player){ + var storage=player.storage.olsaogu; + if(storage) return true; + return player.getDiscardableCards(player,'he').filter(card=>{ + if(event.olsaogu&&event.olsaogu.some(cardx=>get.suit(cardx,false)==get.suit(card,player))) return false; + return true; + }).length>1; + }, + filterCard:function(card,player){ + if(player.storage.olsaogu) return false; + if(_status.event.olsaogu&&_status.event.olsaogu.some(cardx=>get.suit(cardx,false)==get.suit(card,player))) return false; + return true; + }, + selectCard:function(){ + var player=_status.event.player; + return player.storage.olsaogu?-1:2; + }, + position:'he', + check:function(card){ + var player=_status.event.player; + if(card.name=='sha') return player.hasValueTarget(card)?10:0.001; + return 6-get.value(card); + }, + prompt:function(){ + var player=_status.event.player; + var storage=player.storage.olsaogu; + if(storage) return '摸一张牌'; + var list=_status.event.olsaogu,str=''; + if(list&&list.length){ + var text='',suits=list.reduce(function(list,card){ + return list.add(get.suit(card,false)),list; + },[]).sort((a,b)=>lib.suit.indexOf(b)-lib.suit.indexOf(a)); + for(var i=0;icard.name=='sha'); + if(cardx.length){ + var next=game.createEvent('olsaogu_chooseToUseSha'); + next.player=player; + next.cards=cardx; + next.setContent(lib.skill.olsaogu.chooseToUseSha); + } + } + }, + ai:{ + order:function(item,player){ + return get.order({name:'sha'},player)-0.2; + }, + result:{ + player:function(player){ + var storage=player.storage.olsaogu; + if(storage) return 1; + if(player.getDiscardableCards(player,'he').filter(card=>{ + if(card.name!='sha') return false; + if(_status.event.olsaogu&&_status.event.olsaogu.some(cardx=>get.suit(cardx,false)==get.suit(card,player))) return false; + return true; + }).length) return 1; + return 0; + }, + }, + }, + group:'olsaogu_effect', + subSkill:{ + effect:{ + trigger:{player:'phaseJieshuBegin'}, + filter:function(event,player){ + if(_status.connectMode) return player.countCards('he'); + return player.countDiscardableCards(player,'he'); + }, + direct:true, + content:function(){ + 'step 0' + var list=[]; + player.getHistory('lose',evt=>{ + if(evt.type=='discard'&&evt.getParent('phaseJieshu').name=='phaseJieshu') list.addArray(evt.cards2); + }); + event.list=list; + var str,storage=player.storage.olsaogu; + if(storage) str='弃置一张牌,令一名其他角色摸一张牌。'; + else{ + str='弃置一张牌,令一名其他角色弃置两张牌(不能包含你本阶段弃置过的花色),然后其使用弃置的【杀】。'; + if(list.length){ + var text='',suits=list.reduce(function(list,card){ + return list.add(get.suit(card,false)),list; + },[]).sort((a,b)=>lib.suit.indexOf(b)-lib.suit.indexOf(a)); + for(var i=0;i1; + }, + filterCard:lib.filter.cardDiscardable, + position:'he', + complexCard:true, + complexSelect:true, + ai1:function(card){ + var player=_status.event.player; + if(!player.storage.olsaogu&&_status.event.list.some(cardx=>get.suit(cardx,false)==get.suit(card,player))) return 7-get.value(card); + return 5-get.value(card); + }, + ai2:function(target){ + var player=_status.event.player; + var att=get.attitude(player,target); + if(player.storage.olsaogu) return att; + var list=_status.event.list.slice(); + if(ui.selected.cards.length) list.addArray(ui.selected.cards); + var cards=target.getCards('he',card=>{ + if(card.name!='sha'||list.some(cardx=>get.suit(cardx,false)==get.suit(card,target))) return false; + return lib.filter.cardDiscardable(card,target)&&game.hasPlayer(function(current){ + if(!current.canUse(card,target,false)) return false; + return get.effect(current,card,target,target)>0&&get.effect(current,card,target,player)>0; + }); + }); + if(cards.length&&att>0) return Math.sqrt(Math.min(2,cards.length))*cards.reduce(function(num,card){ + var players=game.filterPlayer(current=>target.canUse(card,current,false)); + players.sort((a,b)=>get.effect(b,card,target,target)*get.effect(b,card,target,player)-get.effect(a,card,target,target)*get.effect(a,card,target,player)); + return num=(get.effect(players[0],card,target,target)*get.effect(players[0],card,target,player)); + },0); + return get.effect(target,{name:'guohe_copy2'},player,player)*Math.sqrt(Math.min(2,target.getDiscardableCards(player,'he').filter(card=>{ + return !list.some(cardx=>get.suit(cardx,false)==get.suit(card,target)); + }).length)); + }, + }).set('list',list); + 'step 1' + if(result.bool){ + var cards=result.cards,target=result.targets[0]; + player.logSkill('olsaogu',target); + player.discard(cards); + if(player.storage.olsaogu){ + target.draw(); + event.finish(); + } + else{ + event.target=target; + var list=result.cards.slice(); + player.getHistory('lose',evt=>{ + if(evt.type=='discard'&&evt.getParent('phaseJieshu').name=='phaseJieshu') list.addArray(evt.cards2); + }); + var cards=target.getCards('he',card=>{ + return lib.filter.cardDiscardable(card,target)&&!list.some(cardx=>get.suit(cardx,false)==get.suit(card,target)); + }); + if(cards.length){ + var text='',suits=list.reduce(function(list,card){ + return list.add(get.suit(card,false)),list; + },[]).sort((a,b)=>lib.suit.indexOf(b)-lib.suit.indexOf(a)); + for(var i=0;iget.suit(cardx,false)==get.suit(card,player)); + },Math.min(cards.length,2),true).set('ai',function(card){ + var player=_status.event.player; + if(card.name=='sha'&&player.hasValueTarget(card)) return 10; + return -get.value(card); + }).set('list',list); + } + else event.finish(); + } + } + else event.finish(); + 'step 2' + if(result.bool){ + var cards=result.cards.filter(card=>card.name=='sha'); + if(cards.length){ + var next=game.createEvent('olsaogu_chooseToUseSha'); + next.player=target; + next.cards=cards; + next.setContent(lib.skill.olsaogu.chooseToUseSha); + } + } + }, + }, + }, + chooseToUseSha:function(){ + 'step 0' + event.cards2=cards.filter(i=>get.position(i,true)=='d'&&player.hasUseTarget(i)); + if(!event.cards2.length) event.finish(); + 'step 1' + if(event.cards2.length==1) event._result={bool:true,links:event.cards2}; + else player.chooseButton(['扫谷:请使用其中的【杀】',event.cards2],true).set('filterButton',button=>{ + return _status.event.player.hasUseTarget(button.link,false); + }).set('ai',button=>{ + return _status.event.player.getUseValue(button.link); + }); + 'step 2' + if(result.bool){ + var card=result.links[0]; + event.cards2.remove(card); + player.$gain2(card,false); + game.delayx(); + player.chooseUseTarget(true,card,false); + } + else event.finish(); + 'step 3' + if(event.cards2.length) event.goto(1); + }, + }, //OL周群 oltianhou:{ audio:2, @@ -721,7 +952,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(!lib.skill.oltianhou.derivation.contains(skill)) event.finish(); else{ event.weather_skill=skill; - player.chooseTarget(true,'令一名角色获得技能【'+get.translation(skill)+'】').set('ai',function(target){ + player.chooseTarget(true,'令一名角色获得技能【'+get.translation(skill)+'】',get.translation(skill+'_info')).set('ai',function(target){ return get.attitude(_status.event.player,target); }); } @@ -990,12 +1221,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var card=event.card; if(card.name!='sha') return false; if(event.player==player){ - if(game.hasPlayer(current=>{ - return current.isIn()&&!event.targets.contains(current)&&player.canUse(event.card,current,false); - })){ - return true; - } - return false; + return game.hasPlayer(current=>{ + return current.isIn()&&!event.targets.contains(current)&&player.canUse(card,current); + }); } return event.player.isIn()&&!event.targets.contains(player)&&event.player.canUse(card,player); }, @@ -1004,7 +1232,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 'step 0' if(trigger.player==player){ player.chooseTarget(get.prompt('olguangao'),'为'+get.translation(trigger.card)+'额外指定一个目标。然后若你手牌数为偶数,你摸一张牌并令此牌对任意目标无效。',(card,player,target)=>{ - return !_status.event.sourcex.contains(target)&&player.canUse(_status.event.card,target,false); + return !_status.event.sourcex.contains(target)&&player.canUse(_status.event.card,target); }).set('sourcex',trigger.targets).set('ai',function(target){ var player=_status.event.player; var eff=get.effect(target,_status.event.card,player,player); @@ -8810,7 +9038,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var type=get.type(trigger.card,false); player.chooseToDiscard('h',get.prompt('olfengzi'),'弃置一张'+get.translation(type)+'牌,令'+get.translation(trigger.card)+'结算两次',function(card,player){ return get.type2(card,player)==_status.event.type; - }).set('type',type).set('ai',()=>-1).logSkill='olfengzi'; + }).set('type',type).set('ai',function(card){ + var player=_status.event.player; + var trigger=_status.event.getTrigger(); + if(trigger.card.name=='tiesuo') return 0; + var num=0; + for(var i of trigger.targets) num+=get.effect(i,trigger.card,player,player); + if(num<=0) return 0; + return 7-get.value(card); + }).logSkill='olfengzi'; 'step 1' if(result.bool){ trigger.effectCount++; @@ -10500,8 +10736,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ selectTarget:[1,Infinity], content:function(){ 'step 0' - if(!target.countCards('he')) event.finish(); - else target.chooseCard('he','交给'+get.translation(player)+'一张牌',true); + if(!target.countCards('h')) event.finish(); + else target.chooseCard('h','交给'+get.translation(player)+'一张牌',true); 'step 1' target.give(result.cards,player); 'step 2' @@ -18118,9 +18354,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, filter:function(event,player){ if(event.targets.length!=1||!['sha','juedou'].contains(event.card.name)) return false; - return player.getHistory('useCard',function(evt){ - return evt.card.name==event.card.name; - }).indexOf(event.getParent())==0; + var evtx=event.getParent(); + return !player.hasHistory('useCard',function(evt){ + return evt!=evtx&&evt.card.name==event.card.name; + },evtx) }, direct:true, content:function(){ @@ -22819,7 +23056,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, luochong:function(player){ var storage=player.getStorage('luochong'); - var str='准备阶段开始时/当你受到伤害后,你可选择本轮内未选择过的一项(每名角色每轮限选一次):' + var str='准备阶段开始时/当你于一回合首次受到伤害后,你可选择本轮内未选择过的一项(每名角色每轮限选一次):' var choiceList=[ '⒈令一名角色回复1点体力。', '⒉令一名角色失去1点体力。', @@ -22865,6 +23102,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(player.storage.olmiuyan) return '转换技。你可以将一张黑色牌当做【火攻】使用。然后若此技能:处于阳状态且此牌造成了伤害,则你获得此阶段内所有被展示过的牌;处于阴状态且未造成伤害,则你令此技能失效直到本轮结束。'; return '转换技。你可以将一张黑色牌当做【火攻】使用。然后若此技能:处于阳状态且此牌造成了伤害,则你获得此阶段内所有被展示过的牌;处于阴状态且未造成伤害,则你令此技能失效直到本轮结束。'; }, + olsaogu:function(player){ + if(player.storage.olsaogu) return '转换技。①出牌阶段,你可以。阴:弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】;阳:摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色执行你当前〖扫谷①〗的分支。'; + return '转换技。①出牌阶段,你可以。阴:弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】;阳:摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色执行你当前〖扫谷①〗的分支。'; + }, }, characterReplace:{ caoshuang:['caoshuang','ns_caoshuang'], @@ -23938,7 +24179,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ olbihun:'弼昏', olbihun_info:'锁定技。当你使用牌指定其他角色为目标时,若你的手牌数大于手牌上限且若此牌的目标数:大于1,取消此目标;为1,其获得此牌。', olchuanwu:'穿屋', - olchuanwu_info:'锁定技。当你造成或受到伤害后,你令武将牌上的前X个未失效的技能失效直到回合结束。然后你摸等同于你此次失效的技能数张牌(X为你的攻击范围)。', + olchuanwu_info:'锁定技。当你造成或受到伤害后,你令武将牌上的前X个技能失效直到回合结束。然后你摸等同于你此次失效的技能数张牌(X为你的攻击范围)。', oljianhe:'剑合', oljianhe_info:'出牌阶段每名角色限一次。你可以重铸至少两张同名牌或至少两张装备牌,然后令一名角色选择一项:1.重铸等量张与你以此法重铸的牌类型相同的牌;2.受到你造成的1点雷电伤害。', dongtuna:'董荼那', @@ -24004,7 +24245,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ olzhenying_info:'出牌阶段限两次。你可以选择一名手牌数不大于你的其他角色,你与其同时将手牌摸或弃置至至多两张。然后你与其中手牌数较少的角色视为对另一名角色使用一张【决斗】。', ol_wenqin:'文钦', olguangao:'犷骜', - olguangao_info:'当你/其他角色使用【杀】时,你/该角色可以额外指定一个目标/你为目标(使用者不为你则有距离限制)。然后若你的手牌数为偶数,你摸一张牌并令此牌对任意目标无效(可不选)。', + olguangao_info:'当你/其他角色使用【杀】时,你/该角色可以额外指定一个目标/你为目标(有距离限制)。然后若你的手牌数为偶数,你摸一张牌并令此牌对任意目标无效(可不选)。', olhuiqi:'彗企', olhuiqi_info:'觉醒技。一名角色回合结束后,若仅有三名角色于此回合成为过牌的目标,你获得〖偕举〗并获得一个额外的回合。', olxieju:'偕举', @@ -24023,6 +24264,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ oltianhou_club_info:'锁定技。其他角色的结束阶段开始时,若其体力值为全场最小,则其失去1点体力。', oltianhou_diamond:'凝雾', oltianhou_diamond_info:'锁定技。其他角色使用【杀】指定与其座次不相邻唯一目标时,则其判定。若判定结果的点数大于此【杀】,则此【杀】对其无效。', + duanjiong:'段颎', + olsaogu:'扫谷', + olsaogu_info:'转换技。①出牌阶段,你可以。阴:弃置两张牌(不能包含你本阶段弃置过的花色),然后使用其中的【杀】;阳:摸一张牌。②结束阶段,你可以弃置一张牌,令一名其他角色执行你当前〖扫谷①〗的分支。', sp_tianji:'天极·皇室宗亲', sp_sibi:'四弼·辅国文曲', @@ -24033,7 +24277,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sp_liesi:'列肆·豪商巨贾', sp_default:"天同·同名异势", sp_qifu:'灯愿·祈福武将', - sp_wanglang:'八萬·饶舌凤鹛', + sp_wanglang:'OL·限定专属', sp_zhongdan:"忠胆英杰", sp_guozhan:"国战", sp_guozhan2:"国战移植", diff --git a/character/sp2.js b/character/sp2.js index 55591f96f8..ddfd92a93d 100644 --- a/character/sp2.js +++ b/character/sp2.js @@ -51,7 +51,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ zhaozhong:['male','qun',6,['yangzhong','huangkong']], hanfu:['male','qun',4,['hfjieying','weipo']], re_quyi:['male','qun',4,['refuqi','jiaozi']], - dongxie:['female','qun','3/4',['juntun','jiaojie']], + dongxie:['female','qun',4,['dcjiaoxia','dchumei']], wangrong:['female','qun',3,['minsi','jijing','zhuide']], ol_dingyuan:['male','qun',4,['cixiao','xianshuai']], xin_baosanniang:['female','shu',3,['decadewuniang','decadexushen']], @@ -111,6 +111,173 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, skill:{ + //董翓 + dcjiaoxia:{ + mod:{ + cardUsableTarget:function(card,player,target){ + if(!player.isPhaseUsing()) return; + if(card.name=='sha'&&!player.getStorage('dcjiaoxia_mark').contains(target)) return true; + }, + }, + audio:2, + trigger:{player:'phaseUseBegin'}, + filter:function(event,player){ + return player.countCards('h'); + }, + check:function(event,player){ + return player.countCards('h',card=>{ + return game.hasPlayer(target=>{ + var cardx=get.autoViewAs({name:'sha'},[card]); + return player.canUse(cardx,target)&&get.effect(target,cardx,player,player)>0&&(!player.hasUseTarget(card)||player.hasValueTarget(card)); + }); + }); + }, + content:function(){ + var cards=player.getCards('h'); + player.addTempSkill('dcjiaoxia_used','phaseUseAfter'); + player.addGaintag(cards,'dcjiaoxia_used'); + }, + group:'dcjiaoxia_load', + subSkill:{ + load:{ + charlotte:true, + trigger:{player:'useCard1'}, + filter:function(event,player){ + if(!player.isPhaseUsing()) return false; + return event.card.name=='sha'&&event.targets&&event.targets.some(target=>!player.getStorage('dcjiaoxia_mark').contains(target)); + }, + forced:true, + popup:false, + firstDo:true, + content:function(){ + player.addTempSkill('dcjiaoxia_mark','phaseUseAfter'); + player.markAuto('dcjiaoxia_mark',trigger.targets.filter(target=>!player.getStorage('dcjiaoxia_mark').contains(target))); + }, + }, + mark:{ + charlotte:true, + onremove:true, + }, + used:{ + mod:{ + aiOrder:function(player,card,num){ + if(get.itemtype(card)=='card'&&card.hasGaintag('dcjiaoxia_used')) return num+1; + }, + cardname:function(card,player){ + if(get.itemtype(card)=='card'&&card.hasGaintag('dcjiaoxia_used')) return 'sha'; + }, + }, + charlotte:true, + onremove:function(player){ + player.removeGaintag('dcjiaoxia_used'); + }, + trigger:{player:'useCardAfter'}, + filter:function(event,player){ + return event.cards&&event.cards.length==1&&player.hasUseTarget(get.copy(event.cards[0]))&&player.getHistory('lose',evt=>{ + if(evt.getParent()!=event) return false; + for(var i in evt.gaintag_map){ + if(evt.gaintag_map[i].contains('dcjiaoxia_used')) return true; + } + return false; + }).length&&player.getHistory('sourceDamage',evt=>evt.card==event.card).length; + }, + direct:true, + content:function(){ + var card=get.copy(trigger.cards[0]); + player.chooseUseTarget(card,get.prompt('dcjiaoxia'),false,false).set('prompt2','视为使用'+get.translation(card)).logSkill='dcjiaoxia'; + }, + }, + }, + }, + dchumei:{ + subSkill:{ + 0:{charlotte:true}, + 1:{charlotte:true}, + 2:{charlotte:true}, + }, + onChooseToUse:function(event){ + if(!game.online&&!event.dchumei_num){ + var player=event.player; + var evtx=event.getParent('phaseUse'); + event.set('dchumei_num',player.getHistory('sourceDamage',function(evt){ + return evt.getParent('phaseUse')==evtx; + }).length); + } + }, + audio:2, + enable:'phaseUse', + filter:function(event,player){ + if(typeof event.dchumei_num!='number') return false; + return game.hasPlayer(target=>lib.skill.dchumei.filterTarget(null,player,target)); + }, + filterTarget:function(card,player,target){ + if(target.getHp()>_status.event.dchumei_num) return false; + if(!player.hasSkill('dchumei_0')) return true; + if(!player.hasSkill('dchumei_1')&&target.countCards('he')) return true; + if(!player.hasSkill('dchumei_2')&&target.isDamaged()) return true; + return false; + }, + content:function(){ + 'step 0' + var str=get.translation(target); + player.chooseButton([ + '狐魅:请选择一项', + [[ + [0,'令'+str+'摸一张牌'], + [1,'令'+str+'交给你一张牌'], + [2,'令'+str+'回复1点体力'], + ].filter(list=>{ + if(player.hasSkill('dchumei_'+list[0])) return false; + if(list[0]==1&&!target.countCards('he')) return false; + if(list[0]==2&&target.isHealthy()) return false; + return true; + }),'textbutton'] + ],true).set('filterButton',button=>{ + var target=_status.event.target; + if(player.hasSkill('dchumei_'+button.link)) return false; + if(button.link==1&&!target.countCards('he')) return false; + if(button.link==2&&target.isHealthy()) return false; + return true; + }).set('ai',function(button){ + var target=_status.event.target; + return [ + get.effect(target,{name:'wuzhong'},player,player)/2, + get.effect(target,{name:'shunshou_copy2'},player,player), + get.recoverEffect(target,player,player), + ][button.link]; + }).set('target',target); + 'step 1' + if(result.bool){ + var num=result.links[0]; + player.addTempSkill('dchumei_'+num,'phaseUseAfter'); + switch(num){ + case 0: + target.draw(); + break; + case 1: + target.chooseCard('狐魅:交给'+get.translation(player)+'一张牌','he',true); + break; + case 2: + target.recover(); + break; + } + if(num!=1) event.finish(); + } + else event.finish(); + 'step 2' + if(result.bool) player.gain(result.cards,target,'giveAuto'); + }, + ai:{ + order:1, + result:{ + target:function(player,target){ + if(!player.hasSkill('dchumei_0')) return 1; + if(!player.hasSkill('dchumei_1')) return -1; + if(!player.hasSkill('dchumei_2')) return 1; + }, + }, + }, + }, //魏关羽 dcdanji:{ audio:'danji', @@ -10060,6 +10227,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ juntun_info:'锁定技,准备阶段,若X大于1,则你减1点体力上限并摸X张牌(X为你的体力上限)。', jiaojie:'狡黠', jiaojie_info:'锁定技,你的红色牌不计入手牌上限。你使用黑色牌无距离和次数限制。', + dcjiaoxia:'狡黠', + dcjiaoxia_info:'①出牌阶段开始时,你可以令自己的所有手牌于此阶段均视为【杀】。若如此做,你使用以此法转化的【杀】造成伤害后,你可以视为使用此牌对应的原卡牌。②出牌阶段,你对你本阶段未使用过【杀】的角色使用【杀】无次数限制。', + dchumei:'狐魅', + dchumei_info:'出牌阶段各限一次,你可以选择一名体力值不大于X的角色,令其:①摸一张牌。②交给你一张牌。③回复1点体力。(X为你本阶段造成伤害的次数)', buchen:'不臣', buchen_info:'隐匿技,你于其他角色的回合登场时,可获得当前回合角色的一张牌。', smyyingshi:'鹰视', diff --git a/character/tw.js b/character/tw.js index 1a56ef2a09..57da671e98 100644 --- a/character/tw.js +++ b/character/tw.js @@ -7447,7 +7447,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ 'step 2' player.chooseToCompare(targets,function(card){ return get.number(card); - }).setContent(lib.skill.twchaofeng.chooseToCompareMeanwhile); + }).setContent('chooseToCompareMeanwhile'); 'step 3' if(result.winner&&result.winner==player){ event.targets.remove(result.winner); @@ -7685,7 +7685,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(result.bool){ event.targets=result.targets; player.logSkill('twchaofeng_compare',event.targets); - player.chooseToCompare(event.targets).setContent(lib.skill.twchaofeng.chooseToCompareMeanwhile); + player.chooseToCompare(event.targets).setContent('chooseToCompareMeanwhile'); } 'step 2' if(result.winner){ @@ -7699,169 +7699,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } } } - }, - chooseToCompareMeanwhile:function(){ - 'step 0' - if(player.countCards('h')==0){ - event.result={cancelled:true,bool:false} - event.finish(); - return; - } - for(var i=0; ievent.maxNum){ - event.maxNum=i[1]; - event.winner=i[0]; - } - else if(event.winner&&i[1]==event.maxNum&&i[0]!=event.winner){ - event.winner=null; - } - } - 'step 6' - event.iwhile++; - event.goto(4); - 'step 7' - var player=event.tempplayer; - event.player=player; - delete event.tempplayer; - var str='无人拼点成功'; - if(event.winner){ - event.result.winner=event.winner; - str=get.translation(event.winner)+'拼点成功'; - game.log(event.winner,'拼点成功'); - event.winner.popup('胜'); - } else game.log('#b无人','拼点成功'); - var list=[player].addArray(targets); - list.remove(event.winner); - for(var i of list){ - i.popup('负'); - } - if(str){ - game.broadcastAll(function(str){ - var dialog=ui.create.dialog(str); - dialog.classList.add('center'); - setTimeout(function(){ - dialog.close(); - },1000); - },str); - } - game.delay(3); - 'step 8' - game.broadcastAll(ui.clear); - 'step 9' - event.cards.add(event.card1); } }, twchuanshu:{ @@ -8910,8 +8747,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, intro:{ content:function(storage,player){ - if(player.storage.twzhengjian) return '其他角色的出牌阶段结束时,若其本阶段内未获得过牌,则你可对其造成1点伤害,然后你可失去此效果并获得〖征建〗的效果二。'; - return '其他角色的出牌阶段结束时,若其本阶段内未获得过牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果二。'; + if(player.storage.twzhengjian) return '其他角色的出牌阶段结束时,若其本阶段内未获得过牌,则你可对其造成1点伤害,然后你可失去此效果并获得〖征建〗的效果一。'; + return '其他角色的出牌阶段结束时,若其本阶段内未获得过牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果一。'; }, }, }, @@ -8936,8 +8773,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return list.length>=Math.ceil(num1/2); }, content:function(){ - player.storage.twzhengjian=true; + 'step 0' + player.awakenSkill('twzhongchi'); + 'step 1' + player.recover(2); player.addSkill('twzhongchi_effect'); + player.storage.twzhengjian=true; + 'step 2' game.delayx(); }, subSkill:{ @@ -11569,7 +11411,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ case 'equip2': target.draw(); break; - case 'equip3': case 'equip4': case 'equip6': + case 'equip3': case 'equip4': case 'equip5': target.recover(); break; } @@ -11595,7 +11437,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var hp=player.hp,hs=player.countCards('h',(card)=>card!=ui.selected.cards[0]); var tp=target.hp,ts=target.countCards('h'); if(sub=='equip2') ts++; - if(tpplayer.countCards('h')||player.group==target.group) player.draw(); }, ai:{ + order:7, result:{ player:function(player,target){ if(player.countCards('h')!player.getStorage('dcposuo_suits').contains(suit)&&player.countCards('hs',card=>get.suit(card,player)==suit)); + if(!suits.length||player.getHistory('sourceDamage',evt=>{ + return evt.player!=player&&evt.getParent('phaseUse')==evtx; + }).length) event.set('dcposuo_cards',undefined); + else{ + var list=[],cards=Array.from(ui.cardPile.childNodes); + cards.addArray(Array.from(ui.discardPile.childNodes)); + game.countPlayer(current=>cards.addArray(current.getCards('hejxs'))); + for(var name of lib.inpile){ + if(!get.tag({name:name},'damage')) continue; + if(cards.some(card=>get.name(card,false)==name&&!get.nature(card,false))){ + for(var suit of suits){ + if(cards.some(card=>get.name(card,false)==name&&!get.nature(card,false)&&get.suit(card,false)==suit)){ + list.push([get.type(name),get.translation(suit),name,undefined,suit]); + } + } + } + if(name=='sha'){ + for(var nature of lib.inpile_nature){ + if(cards.some(card=>get.name(card,false)==name&&get.nature(card,false)==nature)){ + for(var suit of suits){ + if(cards.some(card=>get.name(card,false)==name&&get.nature(card,false)==nature&&get.suit(card,false)==suit)){ + list.push([get.type(name),get.translation(suit),name,nature,suit]); + } + } + } + } + } + } + event.set('dcposuo_cards',list); + } + } + }, + audio:2, + enable:'phaseUse', + filter:function(event,player){ + return event.dcposuo_cards&&event.dcposuo_cards.length; + }, + chooseButton:{ + dialog:function(event,player){ + return ui.create.dialog('婆娑',[event.dcposuo_cards,'vcard'],'hidden'); + }, + check:function(button){ + var player=_status.event.player; + return player.getUseValue({name:button.link[2],nature:button.link[3]}); + }, + backup:function(links,player){ + return { + suit:links[0][4], + filterCard:function(card,player){ + return get.suit(card,player)==lib.skill.dcposuo_backup.suit; + }, + viewAs:{ + name:links[0][2], + nature:links[0][3], + isCard:true, + }, + check:function(card){ + return 6.5-get.value(card); + }, + precontent:function(){ + player.logSkill('dcposuo'); + delete event.result.skill; + player.addTempSkill('dcposuo_suits','phaseUseAfter'); + player.markAuto('dcposuo_suits',[get.suit(event.result.cards[0])]); + }, + } + }, + prompt:function(links,player){ + var suit=links[0][4]; + var name=links[0][2]; + var nature=links[0][3]; + return '将一张'+get.translation(suit)+'牌当作'+(get.translation(nature)||'')+get.translation(name)+'使用'; + }, + }, + ai:{ + order:10, + result:{player:1}, + }, + subSkill:{ + suits:{ + charlotte:true, + onremove:true, + }, + }, + }, + dcxiaoren:{ + audio:2, + trigger:{source:'damageSource'}, + usable:1, + content:function(){ + 'step 0' + player.judge(); + 'step 1' + if(result.color!='red'&&result.color!='black') return; + if(result.color=='red'&&!game.hasPlayer(current=>current.isDamaged())) return; + if(result.color=='black'&&(!trigger.player.isIn()||game.countPlayer()<3)) return; + var next=game.createEvent('dcxiaoren_'+result.color); + next.player=player; + if(result.color=='black') next.target=trigger.player; + next.setContent(lib.skill.dcxiaoren['content_'+result.color]); + }, + content_red:function(){ + 'step 0' + player.chooseTarget('绡刃:是否令一名其他角色回复1点体力?',(card,player,target)=>target.isDamaged()).set('ai',target=>get.recoverEffect(target,_status.event.player,_status.event.player)); + 'step 1' + if(result.bool){ + var target=result.targets[0]; + player.line(target); + target.recover(); + } + }, + content_black:function(){ + 'step 0' + if(target.getPrevious()==player) event._result={control:'下家'}; + else if(target.getNext()==player) event._result={control:'上家'}; + else player.chooseControl('上家','下家').set('prompt','绡刃:请选择一个方向').set('prompt2','对'+get.translation(target)+'上家或下家造成1点伤害,然后你以此方向可重复此流程直到有角色因此死亡或此方向的下个目标为你').set('ai',()=>{ + var player=_status.event.player; + var target=_status.event.target; + var left=0,right=0; + var leftx=target.getPrevious(),lefty=target.getNext(); + while(leftx!=player){ + if(get.damageEffect(leftx,player,player)<0) break; + else{ + left+=get.damageEffect(leftx,player,player); + leftx=leftx.getPrevious(); + } + } + while(rightx!=player){ + if(get.damageEffect(rightx,player,player)<0) break; + else{ + right+=get.damageEffect(rightx,player,player); + rightx=leftx.getPrevious(); + } + } + return left>right?'上家':'下家'; + }).set('target',target); + 'step 1' + if(result.control){ + event.num=1; + player.popup(result.control); + game.log(player,'选择了','#y'+result.control); + event.fangxiang=result.control; + } + else event.finish(); + 'step 2' + var current=target; + for(var i=0;i=0); + 'step 4' + if(result.bool){ + event.num++; + event.goto(2); + } + }, + }, //孙翎鸾 dclingyue:{ audio:2, @@ -108,7 +283,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, content:function(){ var num=1,current=_status.currentPhase; - if(current&&trigger.player!=current){ + if(current&&trigger.source!=current){ var num=0,players=game.players.slice(0).concat(game.dead); for(var target of players){ target.getHistory('sourceDamage',function(evt){ @@ -128,8 +303,61 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var source=player.storage.dcpandi_effect; return get.itemtype(source)!='player'||!source.isIn(); }, + pandi_wrapKey:function(){ + var str = ""; + for(var arg of arguments){ + if(arg === null || arg === undefined){ + str += (arg + "-"); + continue; + } + switch(get.itemtype(arg)){ + case 'player': + str+=("p:"+arg.playerid); + break; + case 'card': + if(arg.cardid){ + str+=("c:"+arg.cardid); + }else{ + str+=("c:"+arg.name); + } + break; + default: + str+=("n:"+arg); + break; + } + str+="-"; + } + return str; + }, + pandi_effect:function(target,card,player,viewer){ + if(!_status.event)return get.effect(target,card,player,viewer); + var key = lib.skill.dcpandi.pandi_wrapKey.apply(null,arguments); + var effect = _status.event.getTempCache('effect',key); + if(effect !== undefined)return effect; + effect = get.effect(target,card,player,viewer); + _status.event.putTempCache('effect',key,effect); + return effect; + }, + pandi_canUse:function(player,card,target,arg1,arg2){ + if(!_status.event)return player.canUse(card,target,arg1,arg2); + var key = lib.skill.dcpandi.pandi_wrapKey.apply(null,arguments); + var effect = _status.event.getTempCache('canUse',key); + if(effect !== undefined)return effect; + effect = player.canUse(card,target,arg1,arg2); + _status.event.putTempCache('canUse',key,effect); + return effect; + }, + pandi_effect_use:function(target,card,player,viewer){ + if(!_status.event)return get.effect_use(target,card,player,viewer); + var key = lib.skill.dcpandi.pandi_wrapKey.apply(null,arguments); + var effect = _status.event.getTempCache('effect_use',key); + if(effect !== undefined)return effect; + effect = get.effect_use(target,card,player,viewer); + _status.event.putTempCache('effect_use',key,effect); + return effect; + }, onChooseToUse:function(event){ - if(!game.online&&event.type=='phase'){ + if(!game.online&&event.type=='phase'&&!event.dcpandi){ var players=game.filterPlayer(function(current){ return current!=event.player&¤t.getHistory('sourceDamage').length==0; }) @@ -162,15 +390,32 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(typeof(card)=='string'){ card={name:card,isCard:true}; } + var key = lib.skill.dcpandi.pandi_wrapKey(card,player,viewer); + if(_status.event){ + var uv = _status.event.getTempCache('getUseValue',key); + if(uv!==undefined){ + return uv; + } + } var targets=game.filterPlayer(); var value=[]; var min=0; var info=get.info(card); - if(!info||info.notarget) return 0; + if(!info||info.notarget){ + if(_status.event){ + _status.event.putTempCache('getUseValue',key,0); + } + return 0; + } var range; var select=get.copy(info.selectTarget); if(select==undefined){ - if(info.filterTarget==undefined) return true; + if(info.filterTarget==undefined) { + if(_status.event){ + _status.event.putTempCache('getUseValue',key,true); + } + return true; + } range=[1,1]; } else if(typeof select=='number') range=[select,select]; @@ -178,11 +423,16 @@ game.import('character',function(lib,game,ui,get,ai,_status){ else if(typeof select=='function') range=select(card,player); if(info.singleCard) range=[1,1]; game.checkMod(card,player,range,'selectTarget',player); - if(!range) return 0; + if(!range){ + if(_status.event){ + _status.event.putTempCache('getUseValue',key,0); + } + return 0; + } for(var i=0;i{ - if(evt.giver!=target||evt.getParent().name=='_yongjian_zengyu') return false; + if(evt.giver!=target||evt.getParent().name=='gift') return false; return evt.cards.length; })) renzhi=true; }); @@ -4849,7 +5102,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } else if(evt.type=='gain'){ var evtx=evt.getParent(); - if(evtx.giver||evtx.getParent().name=='_yongjian_zengyu') return false; + if(evtx.giver||evtx.getParent().name=='gift') return false; var cards=evtx.getg(target); if(!cards.length) return false; var cards2=evtx.getl(current).cards2; @@ -4860,7 +5113,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return false; })) guojue=true; if(!renzhi&¤t.hasHistory('gain',evt=>{ - if(evt.giver!=target||evt.getParent().name=='_yongjian_zengyu') return false; + if(evt.giver!=target||evt.getParent().name=='gift') return false; return evt.cards.length; })) renzhi=true; }); @@ -5566,7 +5819,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var evt=trigger.getl(player); var num=0; player.getHistory('lose',function(evt){ - if(!goon||evt.type!='discard') return false; + if(evt.type!='discard') return false; num+=evt.cards2.length; }); var cards=[]; @@ -5597,52 +5850,148 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ 'step 0' var list=lib.skill.dchuishu.getList(player); - event.initial_list=list.slice(0); - var min=list[0]; + var min=list[0],max=list[0]; for(var i of list){ if(imax) max=i; } var exps=['摸牌数[','弃牌数[','目标牌数[']; - var choices=[]; + var choices_min=[],choices_max=[]; for(var i=0;i'; + td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ + if(_status.dragged) return; + if(_status.justdragged) return; + _status.tempNoButton=true; + setTimeout(function(){ + _status.tempNoButton=false; + },500); + var link=this.link; + var current=this.parentNode.querySelector('.bluebg'); + if(current) current.classList.remove('bluebg'); + this.classList.add('bluebg'); + event._result.min=link; + }); + } + dialog.content.appendChild(table); + dialog.addText('最大值-1'); + var table2=document.createElement('div'); + table2.classList.add('add-setting'); + table2.style.margin='0'; + table2.style.width='100%'; + table2.style.position='relative'; + for(var i=0;i'; + td.addEventListener(lib.config.touchscreen?'touchend':'click',function(){ + if(_status.dragged) return; + if(_status.justdragged) return; + _status.tempNoButton=true; + setTimeout(function(){ + _status.tempNoButton=false; + },500); + var link=this.link; + var current=this.parentNode.querySelector('.bluebg'); + if(current) current.classList.remove('bluebg'); + this.classList.add('bluebg'); + event._result.max=link; + }); + } + dialog.content.appendChild(table2); + dialog.add('  '); + event.dialog.open(); + + event.switchToAuto=function(){ + event._result={ + bool:true, + min:min[0], + max:max[0], + }; + event.dialog.close(); + event.control.close(); + game.resume(); + _status.imchoosing=false; + }; + event.control=ui.create.control('ok',function(link){ + var result=event._result; + if(!result.min||!result.max) return; + result.bool=true; + event.dialog.close(); + event.control.close(); + game.resume(); + _status.imchoosing=false; + }); + for(var i=0;i{ - return target.countCards('he')>0&&target!=player&&target!=_status.event.getParent().target; - }); - next.set('ai',target=>{ - return -get.attitude(_status.event.player,target)*target.countCards('he')+0.1; - }); + if(game.hasPlayer(current=>{ + return current.countCards('he')>0&¤t!=player&¤t!=target; + })){ + var color=get.color(result.cards[0],result.cards[0].original=='j'?false:target); + event.color=color; + var next=player.chooseTarget(true,'挫锐:选择另一名其他角色','弃置该角色装备区里至多两张'+get.translation(event.color)+'牌;或展示该角色的至多两张手牌,然后获得其中的'+get.translation(event.color)+'牌'); + next.set('filterTarget',(card,player,target)=>{ + return target.countCards('he')>0&&target!=player&&target!=_status.event.getParent().target; + }); + next.set('ai',target=>{ + return -get.attitude(_status.event.player,target)*target.countCards('he')+0.1; + }); + } + else event.finish(); 'step 8' if(result.bool){ var targetx=result.targets[0]; @@ -11231,6 +11586,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ganfurenmifuren:'甘夫人,刘备起兵后于沛城娶之为妾。后来,甘夫人随刘备到荆州,生了阿斗(也就是后主刘禅)。223年四月,刘备病死于白帝城,追谥甘夫人为“昭烈皇后”。
    糜夫人,刘备夫人。徐州别驾糜竺之妹。长坂兵败,她怀抱年仅两岁的刘禅在乱军中走散,被赵云发现;但麋夫人因为赵云只有一匹马,不肯上马,在将阿斗托付给赵云后投井而亡。', sunlingluan:'孙翎鸾,孙坚与妾室丁氏的女儿,孙策的妹妹,孙权、孙尚香的姐姐。孙翎年幼时曾得杜夔点化,窥得音律玄妙,丝竹八音,擅长琵琶,每次弹奏琵琶时,经常引来百鸟,称为奇观。早年孙翎鸾出游,山林巧遇葛玄,葛玄观其面相为吉,特传授修行辟谷之法,可令其身心洗涤,容颜久存。孙翎鸾有恋人名张奋,两人情投意合,可惜造化弄人,张奋病死外域,孙翎鸾倚楼盼归,日复一日、年复一年。后有五彩孔雀自东南而来,绕楼而鸣,其声如慕,孙翎鸾泪染笑靥,与孔雀耳语几句后乘翎而去。', zhoubuyi:'周不疑(192年—208年),字元直(或作“文直”),零陵重安(今湖南衡阳县)人,刘表别驾刘先的外甥,少有异才,聪明敏达,在十七岁时就著有文论四首。曹冲死后,曹操怀疑曹丕无法驾驭周不疑,于是派人杀了周不疑。', + tianshangyi:'田尚衣,一作陈尚衣,魏文帝曹丕宫中著名宫人。能歌善舞,一时冠绝于世,私以为比之汉宫飞燕也不遑多让。', }, characterTitle:{ // wulan:'#b对决限定武将', @@ -11312,6 +11668,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ fengfangnv:['re_fengfangnv','fengfangnv'], luotong:['luotong','dc_luotong'], dc_wangchang:['dc_wangchang','tw_wangchang'], + guozhao:['guozhao','xin_guozhao'], }, translate:{ puyuan:'蒲元', @@ -11547,7 +11904,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dchuishu:'慧淑', dchuishu_info:'摸牌阶段结束时,你可以摸[3]张牌。若如此做:你弃置[1]张手牌,且当你于本回合内弃置第[2]+1张牌后,你从弃牌堆中随机获得等同于本回合弃牌数的锦囊牌。', dcyishu:'易数', - dcyishu_info:'锁定技。当你不因出牌阶段而失去牌后,你令A={〖慧淑〗的中括号内最小的数字},B={〖慧淑〗的中括号内最大的数字}。然后你令A中的一个数字+2,且B中的一个数字-1。', + dcyishu_info:'锁定技。当你不因出牌阶段而失去牌后,你同时令{〖慧淑〗的中括号内最小的一个数字+2}且{〖慧淑〗的中括号内最大的一个数字-1}。', dcligong:'离宫', dcligong_info:'觉醒技。准备阶段,若〖慧淑〗的中括号内有不小于5的数字,则你加1点体力上限,回复1点体力并失去〖易数〗。系统随机检索四张吴势力的女性武将牌,然后你选择一项:⒈摸三张牌。⒉失去〖慧淑〗,然后获得这些武将牌上的任意两个非Charlotte技能。', dingshangwan:'丁尚涴', @@ -11746,6 +12103,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcchangqu_info:'出牌阶段限一次。你可以开一艘战舰(你从你的上家或下家开始选择任意名座位连续的其他角色,且起点角色获得“战舰”标记)。这些角色按照你选择的顺序依次执行:{若其有本次获得的“战舰”,其选择一项:1.交给你X张手牌,然后将“战舰”移动给你选择的下一名目标角色;2.令其下次受到的属性伤害值+X,然后横置(X为本次〖长驱〗中选项一被选择过的次数且至少为1)。}。', dctongye:'统业', dctongye_info:'锁定技。游戏开始时或一名角色死亡后,若场上势力数:不大于4,你的手牌上限+3;不大于3,你的攻击范围+3;不大于2,你使用【杀】的次数上限+3;不大于1,你摸牌阶段额定摸牌数+3。', + tianshangyi:'田尚衣', + dcposuo:'婆娑', + dcposuo_info:'出牌阶段,若你本阶段未造成过伤害,则你可以将一张你本阶段未以此法使用过的花色的手牌当作任意一张存在于游戏的同花色伤害牌使用。', + dcxiaoren:'绡刃', + dcxiaoren_info:'每回合限一次,当你造成伤害后,你可以进行判定,若结果为:红色,你可以令一名角色回复1点体力;黑色,你可以对受伤角色的上家或下家造成1点伤害,然后你可以重复此方向的伤害流程直到有角色因此死亡或下个目标角色为你。', sp2_yinyu:'隐山之玉', sp2_huben:'百战虎贲', diff --git a/character/yijiang.js b/character/yijiang.js index fd8a989329..89230364f6 100755 --- a/character/yijiang.js +++ b/character/yijiang.js @@ -34,7 +34,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ caozhi:['male','wei',3,['luoying','jiushi']], caochong:['male','wei',3,['chengxiang','renxin']], xunyou:['male','wei',3,['qice','zhiyu'],['clan:颍川荀氏']], - xin_xushu:['male','shu',3,['xinwuyan','xinjujian']], + xin_xushu:['male','shu',3,['xinwuyan','xinjujian'],['border:wei']], xin_masu:['male','shu',3,['olsanyao','rezhiman']], zhuran:['male','wu',4,['danshou']], xusheng:['male','wu',4,['xinpojun']], @@ -7931,6 +7931,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ respondSha:true, }, audio:2, + audioname:['xin_zhangyi'], trigger:{player:['useCard1','respond']}, firstDo:true, forced:true, @@ -13566,7 +13567,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ zhuhuan:['re_zhuhuan','xin_zhuhuan','zhuhuan','old_zhuhuan'], caoxiu:['re_caoxiu','tw_caoxiu','xin_caoxiu','caoxiu','old_caoxiu'], xiahoushi:['re_xiahoushi','xiahoushi'], - zhangyi:['re_zhangyi','zhangyi'], + zhangyi:['xin_zhangyi','re_zhangyi','zhangyi'], quancong:['old_quancong','re_quancong','xin_quancong','quancong'], sunxiu:['re_sunxiu','xin_sunxiu','sunxiu'], zhuzhi:['re_zhuzhi','zhuzhi','xin_zhuzhi','old_zhuzhi'], diff --git a/font/huangcao.ttf b/font/huangcao.ttf deleted file mode 100644 index 8f08e021d8..0000000000 Binary files a/font/huangcao.ttf and /dev/null differ diff --git a/font/huangcao.woff2 b/font/huangcao.woff2 new file mode 100644 index 0000000000..18d1ed9877 Binary files /dev/null and b/font/huangcao.woff2 differ diff --git a/font/shousha.ttf b/font/shousha.ttf deleted file mode 100644 index fe8ea1b0a7..0000000000 Binary files a/font/shousha.ttf and /dev/null differ diff --git a/font/shousha.woff2 b/font/shousha.woff2 new file mode 100644 index 0000000000..018f25661c Binary files /dev/null and b/font/shousha.woff2 differ diff --git a/font/suits.ttf b/font/suits.ttf deleted file mode 100644 index b87937b605..0000000000 Binary files a/font/suits.ttf and /dev/null differ diff --git a/font/suits.woff2 b/font/suits.woff2 new file mode 100644 index 0000000000..f1097cdf55 Binary files /dev/null and b/font/suits.woff2 differ diff --git a/font/xiaozhuan.ttf b/font/xiaozhuan.ttf deleted file mode 100644 index 33eb29f715..0000000000 Binary files a/font/xiaozhuan.ttf and /dev/null differ diff --git a/font/xiaozhuan.woff2 b/font/xiaozhuan.woff2 new file mode 100644 index 0000000000..a7b92a61a6 Binary files /dev/null and b/font/xiaozhuan.woff2 differ diff --git a/font/xingkai.woff2 b/font/xingkai.woff2 new file mode 100644 index 0000000000..1120aac6af Binary files /dev/null and b/font/xingkai.woff2 differ diff --git a/font/xinwei.ttf b/font/xinwei.ttf deleted file mode 100644 index 013ca4b25d..0000000000 Binary files a/font/xinwei.ttf and /dev/null differ diff --git a/font/xingkai.ttf b/font/xinwei.woff2 similarity index 50% rename from font/xingkai.ttf rename to font/xinwei.woff2 index 6ab8be042e..51e1122db5 100644 Binary files a/font/xingkai.ttf and b/font/xinwei.woff2 differ diff --git a/font/yuanli.ttf b/font/yuanli.ttf deleted file mode 100644 index bca33e79e8..0000000000 Binary files a/font/yuanli.ttf and /dev/null differ diff --git a/font/yuanli.woff2 b/font/yuanli.woff2 new file mode 100644 index 0000000000..70e451a2e1 Binary files /dev/null and b/font/yuanli.woff2 differ diff --git a/game/asset.js b/game/asset.js index e221a310e3..0859dd4eda 100644 --- a/game/asset.js +++ b/game/asset.js @@ -233,15 +233,18 @@ window.noname_asset_list=[ 'audio/die/chunyuqiong.mp3', 'audio/die/clan_hanrong.mp3', 'audio/die/clan_hanshao.mp3', + 'audio/die/clan_wanghun.mp3', 'audio/die/clan_wangling.mp3', 'audio/die/clan_wangyun.mp3', 'audio/die/clan_wuban.mp3', + 'audio/die/clan_wukuang.mp3', 'audio/die/clan_wuxian.mp3', 'audio/die/clan_xuncai.mp3', 'audio/die/clan_xuncan.mp3', 'audio/die/clan_xunchen.mp3', 'audio/die/clan_xunshu.mp3', 'audio/die/clan_zhonghui.mp3', + 'audio/die/clan_zhongyan.mp3', 'audio/die/cuimao.mp3', 'audio/die/cuiyan.mp3', 'audio/die/daqiao.mp3', @@ -301,9 +304,11 @@ window.noname_asset_list=[ 'audio/die/dongcheng.mp3', 'audio/die/dongguiren.mp3', 'audio/die/dongtuna.mp3', + 'audio/die/dongxie.mp3', 'audio/die/dongyun.mp3', 'audio/die/dongzhao.mp3', 'audio/die/dongzhuo.mp3', + 'audio/die/duanjiong.mp3', 'audio/die/duanqiaoxiao.mp3', 'audio/die/duanwei.mp3', 'audio/die/dufuren.mp3', @@ -572,6 +577,7 @@ window.noname_asset_list=[ 'audio/die/ol_sunjian.mp3', 'audio/die/ol_wangrong.mp3', 'audio/die/ol_weiyan.mp3', + 'audio/die/ol_wenqin.mp3', 'audio/die/ol_xiahouyuan.mp3', 'audio/die/ol_xiaoqiao.mp3', 'audio/die/ol_xuhuang.mp3', @@ -600,6 +606,7 @@ window.noname_asset_list=[ 'audio/die/panshu.mp3', 'audio/die/panzhangmazhong.mp3', 'audio/die/peixiu.mp3', + 'audio/die/peiyuanshao.mp3', 'audio/die/puyuan.mp3', 'audio/die/qianzhao.mp3', 'audio/die/qiaogong.mp3', @@ -777,6 +784,7 @@ window.noname_asset_list=[ 'audio/die/sb_yuanshao.mp3', 'audio/die/sb_yujin.mp3', 'audio/die/sb_zhangfei.mp3', + 'audio/die/sb_zhanghe.mp3', 'audio/die/sb_zhangjiao.mp3', 'audio/die/sb_zhaoyun.mp3', 'audio/die/sb_zhenji.mp3', @@ -1034,6 +1042,7 @@ window.noname_asset_list=[ 'audio/die/xin_gaoshun.mp3', 'audio/die/xin_gongsunzan.mp3', 'audio/die/xin_guohuai.mp3', + 'audio/die/xin_guozhao.mp3', 'audio/die/xin_guyong.mp3', 'audio/die/xin_handang.mp3', 'audio/die/xin_hansui.mp3', @@ -1053,6 +1062,7 @@ window.noname_asset_list=[ 'audio/die/xin_yuanshao.mp3', 'audio/die/xin_yufan.mp3', 'audio/die/xin_yuji.mp3', + 'audio/die/xin_zhangyi.mp3', 'audio/die/xin_zhonghui.mp3', 'audio/die/xin_zhuhuan.mp3', 'audio/die/xin_zhuran.mp3', @@ -1535,6 +1545,7 @@ window.noname_asset_list=[ 'audio/skill/chuanyun.mp3', 'audio/skill/chuhai1.mp3', 'audio/skill/chuhai2.mp3', + 'audio/skill/chuhai3.mp3', 'audio/skill/chuiti1.mp3', 'audio/skill/chuiti2.mp3', 'audio/skill/chulao1.mp3', @@ -1557,10 +1568,14 @@ window.noname_asset_list=[ 'audio/skill/clanbalong2.mp3', 'audio/skill/clanbaozu_clan_zhonghui1.mp3', 'audio/skill/clanbaozu_clan_zhonghui2.mp3', + 'audio/skill/clanbaozu_clan_zhongyan1.mp3', + 'audio/skill/clanbaozu_clan_zhongyan2.mp3', 'audio/skill/clanbeishi1.mp3', 'audio/skill/clanbeishi2.mp3', 'audio/skill/clanbolong1.mp3', 'audio/skill/clanbolong2.mp3', + 'audio/skill/clanchenya1.mp3', + 'audio/skill/clanchenya2.mp3', 'audio/skill/clandaojie_clan_xuncai1.mp3', 'audio/skill/clandaojie_clan_xuncai2.mp3', 'audio/skill/clandaojie_clan_xuncan1.mp3', @@ -1575,6 +1590,10 @@ window.noname_asset_list=[ 'audio/skill/clanfangzhen2.mp3', 'audio/skill/clanfenchai1.mp3', 'audio/skill/clanfenchai2.mp3', + 'audio/skill/clanfuxun1.mp3', + 'audio/skill/clanfuxun2.mp3', + 'audio/skill/clanguangu1.mp3', + 'audio/skill/clanguangu2.mp3', 'audio/skill/clanguixiang1.mp3', 'audio/skill/clanguixiang2.mp3', 'audio/skill/clanhuanjia1.mp3', @@ -1585,6 +1604,8 @@ window.noname_asset_list=[ 'audio/skill/clanjiexuan2.mp3', 'audio/skill/clanlianhe1.mp3', 'audio/skill/clanlianhe2.mp3', + 'audio/skill/clanlianzhu1.mp3', + 'audio/skill/clanlianzhu2.mp3', 'audio/skill/clanlieshi1.mp3', 'audio/skill/clanlieshi2.mp3', 'audio/skill/clanliuju1.mp3', @@ -1593,6 +1614,8 @@ window.noname_asset_list=[ 'audio/skill/clanmingjie2.mp3', 'audio/skill/clanmuyin_clan_wuban1.mp3', 'audio/skill/clanmuyin_clan_wuban2.mp3', + 'audio/skill/clanmuyin_clan_wukuang1.mp3', + 'audio/skill/clanmuyin_clan_wukuang2.mp3', 'audio/skill/clanmuyin_clan_wuxian1.mp3', 'audio/skill/clanmuyin_clan_wuxian2.mp3', 'audio/skill/clansankuang1.mp3', @@ -1601,6 +1624,8 @@ window.noname_asset_list=[ 'audio/skill/clanshangshen2.mp3', 'audio/skill/clanshenjun1.mp3', 'audio/skill/clanshenjun2.mp3', + 'audio/skill/clanxiaoyong1.mp3', + 'audio/skill/clanxiaoyong2.mp3', 'audio/skill/clanxieshu1.mp3', 'audio/skill/clanxieshu2.mp3', 'audio/skill/clanxumin_clan_hanrong1.mp3', @@ -1615,6 +1640,8 @@ window.noname_asset_list=[ 'audio/skill/clanyuzhi2.mp3', 'audio/skill/clanzhanding1.mp3', 'audio/skill/clanzhanding2.mp3', + 'audio/skill/clanzhongliu_clan_wanghun1.mp3', + 'audio/skill/clanzhongliu_clan_wanghun2.mp3', 'audio/skill/clanzhongliu_clan_wangling1.mp3', 'audio/skill/clanzhongliu_clan_wangling2.mp3', 'audio/skill/clanzhongliu_clan_wangyun1.mp3', @@ -1786,6 +1813,8 @@ window.noname_asset_list=[ 'audio/skill/dchuishu2.mp3', 'audio/skill/dchuizhi1.mp3', 'audio/skill/dchuizhi2.mp3', + 'audio/skill/dchumei1.mp3', + 'audio/skill/dchumei2.mp3', 'audio/skill/dcjianguo1.mp3', 'audio/skill/dcjianguo2.mp3', 'audio/skill/dcjianji1.mp3', @@ -1796,6 +1825,8 @@ window.noname_asset_list=[ 'audio/skill/dcjianzheng2.mp3', 'audio/skill/dcjiaofeng1.mp3', 'audio/skill/dcjiaofeng2.mp3', + 'audio/skill/dcjiaoxia1.mp3', + 'audio/skill/dcjiaoxia2.mp3', 'audio/skill/dcjieshu1.mp3', 'audio/skill/dcjieshu2.mp3', 'audio/skill/dcjiexing1.mp3', @@ -1870,6 +1901,8 @@ window.noname_asset_list=[ 'audio/skill/dcminze2.mp3', 'audio/skill/dcmiyun1.mp3', 'audio/skill/dcmiyun2.mp3', + 'audio/skill/dcmoyu1.mp3', + 'audio/skill/dcmoyu2.mp3', 'audio/skill/dcneifa1.mp3', 'audio/skill/dcneifa2.mp3', 'audio/skill/dcnuchen1.mp3', @@ -3320,12 +3353,16 @@ window.noname_asset_list=[ 'audio/skill/olfusong2.mp3', 'audio/skill/olgoude1.mp3', 'audio/skill/olgoude2.mp3', + 'audio/skill/olguangao1.mp3', + 'audio/skill/olguangao2.mp3', 'audio/skill/olhaoshi1.mp3', 'audio/skill/olhaoshi2.mp3', 'audio/skill/olhongji1.mp3', 'audio/skill/olhongji2.mp3', 'audio/skill/olhuanfu1.mp3', 'audio/skill/olhuanfu2.mp3', + 'audio/skill/olhuiqi1.mp3', + 'audio/skill/olhuiqi2.mp3', 'audio/skill/olhunzi_re_sunyi1.mp3', 'audio/skill/olhunzi_re_sunyi2.mp3', 'audio/skill/olhunzi1.mp3', @@ -3370,6 +3407,8 @@ window.noname_asset_list=[ 'audio/skill/olqisi2.mp3', 'audio/skill/olruoyu1.mp3', 'audio/skill/olruoyu2.mp3', + 'audio/skill/olsaogu1.mp3', + 'audio/skill/olsaogu2.mp3', 'audio/skill/olshengong1.mp3', 'audio/skill/olshengong2.mp3', 'audio/skill/olshilu1.mp3', @@ -3396,6 +3435,8 @@ window.noname_asset_list=[ 'audio/skill/olxiaosi2.mp3', 'audio/skill/olxibing1.mp3', 'audio/skill/olxibing2.mp3', + 'audio/skill/olxieju1.mp3', + 'audio/skill/olxieju2.mp3', 'audio/skill/olximo1.mp3', 'audio/skill/olximo2.mp3', 'audio/skill/olximo3.mp3', @@ -4103,6 +4144,8 @@ window.noname_asset_list=[ 'audio/skill/sbniepan2.mp3', 'audio/skill/sbpaoxiao1.mp3', 'audio/skill/sbpaoxiao2.mp3', + 'audio/skill/sbqiaobian1.mp3', + 'audio/skill/sbqiaobian2.mp3', 'audio/skill/sbqiaoshi1.mp3', 'audio/skill/sbqiaoshi2.mp3', 'audio/skill/sbqingzheng1.mp3', @@ -4863,6 +4906,8 @@ window.noname_asset_list=[ 'audio/skill/wfyuyan2.mp3', 'audio/skill/wlcuorui1.mp3', 'audio/skill/wlcuorui2.mp3', + 'audio/skill/wufei1.mp3', + 'audio/skill/wufei2.mp3', 'audio/skill/wuhun21.mp3', 'audio/skill/wuhun22.mp3', 'audio/skill/wuhun23.mp3', @@ -5236,6 +5281,9 @@ window.noname_asset_list=[ 'audio/skill/xinshenxing2.mp3', 'audio/skill/xintan1.mp3', 'audio/skill/xintan2.mp3', + 'audio/skill/xinwurong1.mp3', + 'audio/skill/xinwurong2.mp3', + 'audio/skill/xinwurong3.mp3', 'audio/skill/xinwusheng1.mp3', 'audio/skill/xinwusheng2.mp3', 'audio/skill/xinwuyan1.mp3', @@ -5378,6 +5426,8 @@ window.noname_asset_list=[ 'audio/skill/yeyan3.mp3', 'audio/skill/yicheng1.mp3', 'audio/skill/yicheng2.mp3', + 'audio/skill/yichong1.mp3', + 'audio/skill/yichong2.mp3', 'audio/skill/yicong1.mp3', 'audio/skill/yicong2.mp3', 'audio/skill/yicong3.mp3', @@ -5835,12 +5885,12 @@ window.noname_asset_list=[ 'audio/voice/female/21.mp3', 'audio/voice/female/22.mp3', - 'font/huangcao.ttf', - 'font/shousha.ttf', - 'font/xiaozhuan.ttf', - 'font/xingkai.ttf', - 'font/xinwei.ttf', - 'font/yuanli.ttf', + 'font/huangcao.woff2', + 'font/shousha.woff2', + 'font/xiaozhuan.woff2', + 'font/xingkai.woff2', + 'font/xinwei.woff2', + 'font/yuanli.woff2', 'image/background/beipan_bg.jpg', 'image/background/heaven_bg.jpg', @@ -5907,14 +5957,18 @@ window.noname_asset_list=[ 'image/card/dawan.png', 'image/card/db_atk1.jpg', 'image/card/db_atk1_出阵迎战.jpg', + 'image/card/db_atk1_反抗.jpg', 'image/card/db_atk1_固守城池.jpg', 'image/card/db_atk2.jpg', 'image/card/db_atk2_拱卫中军.jpg', + 'image/card/db_atk2_归顺.jpg', 'image/card/db_atk2_突出重围.jpg', 'image/card/db_def1.jpg', 'image/card/db_def1_围城断粮.jpg', + 'image/card/db_def1_镇压.jpg', 'image/card/db_def1_直取敌营.jpg', 'image/card/db_def2.jpg', + 'image/card/db_def2_安抚.jpg', 'image/card/db_def2_擂鼓进军.jpg', 'image/card/db_def2_扰阵疲敌.jpg', 'image/card/diaobingqianjiang.png', @@ -6502,10 +6556,12 @@ window.noname_asset_list=[ 'image/character/dongcheng.jpg', 'image/character/dongguiren.jpg', 'image/character/dongtuna.jpg', + 'image/character/dongwan.jpg', 'image/character/dongxie.jpg', 'image/character/dongyun.jpg', 'image/character/dongzhao.jpg', 'image/character/dongzhuo.jpg', + 'image/character/duanjiong.jpg', 'image/character/duanqiaoxiao.jpg', 'image/character/duanwei.jpg', 'image/character/dufuren.jpg', @@ -7258,6 +7314,7 @@ window.noname_asset_list=[ 'image/character/old_wanglang.jpg', 'image/character/old_wangyi.jpg', 'image/character/old_wangyun.jpg', + 'image/character/old_xiaoqiao.jpg', 'image/character/old_xusheng.jpg', 'image/character/old_yangyan.jpg', 'image/character/old_yangzhi.jpg', @@ -7348,6 +7405,7 @@ window.noname_asset_list=[ 'image/character/pe_wenqin.jpg', 'image/character/pe_zhonghui.jpg', 'image/character/peixiu.jpg', + 'image/character/peiyuanshao.jpg', 'image/character/pengyang.jpg', 'image/character/pk_sp_duyu.jpg', 'image/character/prp_zhugeliang.jpg', @@ -8001,6 +8059,7 @@ window.noname_asset_list=[ 'image/character/xin_masu.jpg', 'image/character/xin_panzhangmazhong.jpg', 'image/character/xin_quancong.jpg', + 'image/character/xin_sunliang.jpg', 'image/character/xin_sunluban.jpg', 'image/character/xin_sunxiu.jpg', 'image/character/xin_wuguotai.jpg', diff --git a/game/game.js b/game/game.js index 7ffcdf8fbe..16ba866924 100644 --- a/game/game.js +++ b/game/game.js @@ -1,5 +1,5 @@ "use strict"; -(function(){ +(()=>{ if(!localStorage.getItem('gplv3_noname_alerted')){ if(confirm('①无名杀是一款基于GPLv3协议的开源软件!\n你可以在遵守GPLv3协议的基础上任意使用,修改并转发《无名杀》,以及所有基于《无名杀》开发的拓展。\n点击“确定”即代表您认可并接受GPLv3协议↓️\nhttps://www.gnu.org/licenses/gpl-3.0.html\n②无名杀官方发布地址仅有GitHub仓库!\n其他所有的所谓“无名杀”社群(包括但不限于绝大多数“官方”QQ群、QQ频道等)均为玩家自发组织,与无名杀官方无关!')){ localStorage.setItem('gplv3_noname_alerted',true); @@ -29,7 +29,7 @@ } } } - var _status={ + const _status={ paused:false, paused2:false, paused3:false, @@ -59,12 +59,13 @@ yingbian_kongchao:[], yingbian_fujia:[], yingbian_canqu:[], + yingbian_force:[] }, renku:[], prehidden_skills:[], postReconnect:{}, }; - var lib={ + const lib={ configprefix:'noname_0.9_', versionOL:27, updateURLS:{ @@ -110,6 +111,7 @@ skill:{}, card:{}, }, + onload:[], arenaReady:[], onfree:[], inpile:[], @@ -149,6 +151,177 @@ }, } }, + yingbian:{ + condition:{ + color:new Map([ + ['zhuzhan','wood'], + ['kongchao','soil'], + ['fujia','orange'], + ['canqu','fire'], + ['force','metal'] + ]), + complex:new Map([ + ['zhuzhan',function(event){ + const yingbianZhuzhan=game.createEvent('yingbianZhuzhan'); + yingbianZhuzhan.player=event.player; + yingbianZhuzhan.card=event.card; + yingbianZhuzhan._trigger=event; + yingbianZhuzhan.yingbianZhuzhanAI=event.yingbianZhuzhanAI; + yingbianZhuzhan.afterYingbianZhuzhan=event.afterYingbianZhuzhan; + yingbianZhuzhan.setContent(()=>{ + 'step 0' + event._global_waiting=true; + event.send=(player,card,source,targets,id,id2,yingbianZhuzhanAI,skillState)=>{ + if(skillState) player.applySkills(skillState); + var type=get.type2(card),str=get.translation(source); + if(targets&&targets.length) str+=`对${get.translation(targets)}`; + str+=`使用了${get.translation(card)},是否弃置一张${get.translation(type)}为其助战?`; + player.chooseCard({ + filterCard:(card,player)=>get.type2(card)==type&&lib.filter.cardDiscardable(card,player), + prompt:str, + position:'h', + _global_waiting:true, + id:id, + id2:id2, + ai:typeof yingbianZhuzhanAI=='function'?yingbianZhuzhanAI(player,card,source,targets):cardx=>{ + var info=get.info(card); + if(info&&info.ai&&info.ai.yingbian){ + var ai=info.ai.yingbian(card,source,targets,player); + if(!ai) return 0; + return ai-get.value(cardx); + } + else if(get.attitude(player,source)<=0) return 0; + return 5-get.value(cardx); + } + }); + if(!game.online) return; + _status.event._resultid=id; + game.resume(); + }; + 'step 1' + var type=get.type2(card); + event.list=game.filterPlayer(current=>current!=player&¤t.countCards('h')&&(_status.connectMode||current.hasCard(cardx=>get.type2(cardx)==type,'h'))).sortBySeat(_status.currentPhase||player); + event.id=get.id(); + 'step 2' + if(!event.list.length) event.finish(); + else if(_status.connectMode&&(event.list[0].isOnline()||event.list[0]==game.me)) event.goto(4); + else event.send(event.current=event.list.shift(),event.card,player,trigger.targets,event.id,trigger.parent.id,trigger.yingbianZhuzhanAI); + 'step 3' + if(result.bool){ + event.zhuzhanresult=event.current; + event.zhuzhanresult2=result; + if(event.current!=game.me) game.delayx(); + event.goto(8); + } + else event.goto(2); + 'step 4' + var id=event.id,sendback=(result,player)=>{ + if(result&&result.id==id&&!event.zhuzhanresult&&result.bool){ + event.zhuzhanresult=player; + event.zhuzhanresult2=result; + game.broadcast('cancel',id); + if(_status.event.id==id&&_status.event.name=='chooseCard'&&_status.paused) return ()=>{ + event.resultOL=_status.event.resultOL; + ui.click.cancel(); + if(ui.confirm) ui.confirm.close(); + }; + } + else if(_status.event.id==id&&_status.event.name=='chooseCard'&&_status.paused) return ()=>event.resultOL=_status.event.resultOL; + },withme=false,withol=false,list=event.list; + for(var i=0;i{ + if(value!=player) value.showTimer(); + }); + event.withol=withol; + 'step 5' + if(!result||!result.bool||event.zhuzhanresult) return; + game.broadcast('cancel',event.id); + event.zhuzhanresult=game.me; + event.zhuzhanresult2=result; + 'step 6' + if(event.withol&&!event.resultOL) game.pause(); + 'step 7' + game.players.forEach(value=>value.hideTimer()); + 'step 8' + if(event.zhuzhanresult){ + var target=event.zhuzhanresult; + target.line(player,'green'); + target.discard(event.zhuzhanresult2.cards).discarder=target; + if(typeof event.afterYingbianZhuzhan=='function') event.afterYingbianZhuzhan(event,trigger); + var yingbianCondition=event.name.slice(8).toLowerCase(),yingbianConditionTag=`yingbian_${yingbianCondition}_tag`; + target.popup(yingbianConditionTag,lib.yingbian.condition.color.get(yingbianCondition)); + game.log(target,'响应了',player,'发起的',yingbianConditionTag); + target.addExpose(0.2); + event.result={ + bool:true + } + } + else event.result={ + bool:false + }; + }); + yingbianZhuzhan._args=Array.from(arguments); + return yingbianZhuzhan; + }] + ]), + simple:new Map([ + ['kongchao',event=>!event.player.countCards('h')], + ['fujia',event=>event.player.isMaxHandcard()], + ['canqu',event=>event.player.getHp()==1] + ]) + }, + effect:new Map([ + ['add',()=>{ + trigger.yingbian_addTarget=true; + }], + ['remove',()=>{ + trigger.yingbian_removeTarget=true; + }], + ['damage',()=>{ + if(typeof trigger.baseDamage!='number') trigger.baseDamage=1; + trigger.baseDamage++; + game.log(card,'的伤害值基数+1'); + }], + ['draw',()=>{ + player.draw(); + }], + ['gain',()=>{ + const cardx=trigger.respondTo; + if(cardx&&cardx[1]&&cardx[1].cards&&cardx[1].cards.filterInD('od').length) player.gain(cardx[1].cards.filterInD('od'),'gain2'); + }], + ['hit',()=>{ + trigger.directHit.addArray(game.players).addArray(game.dead); + game.log(card,'不可被响应'); + }], + ['all',()=>{ + card.yingbian_all=true; + game.log(card,'执行所有选项'); + }] + ]), + prompt:new Map([ + ['add','当你使用此牌选择目标后,你可为此牌增加一个目标'], + ['remove','当你使用此牌选择目标后,你可为此牌减少一个目标'], + ['damage','此牌的伤害值基数+1'], + ['draw','当你声明使用此牌时,你摸一张牌'], + ['gain','当你声明使用此牌时,你获得此牌响应的目标牌'], + ['hit','此牌不可被响应'], + ['all','此牌的效果改为依次执行所有选项'] + ]) + }, characterDialogGroup:{ '收藏':function(name,capt){ return lib.config.favouriteCharacter.contains(name)?capt:null; @@ -2746,10 +2919,12 @@ switch(item){ case 'default': var node=hs[i]._tempName; + node.classList.add('vertical'); node.innerHTML=get.verticalStr(node.tempname); break; case 'horizon': var node=hs[i]._tempName; + node.classList.remove('vertical'); node.innerHTML=node.tempname; break; default: @@ -4987,6 +5162,8 @@ else{ map.junzhu.hide(); } + ui.aozhan_bgm=map.aozhan_bgm; + map.aozhan_bgm._link.config.updatex.call(map.aozhan_bgm,[]); }, guozhan_mode:{ name:'游戏模式', @@ -5039,6 +5216,17 @@ intro:'若开启此选项,所有的玩家将在挑选武将后,分发起始手牌之前,分别观看自己下家的副将。', }, aozhan_bgm:{ + updatex:function(){ + this.lastChild.innerHTML=this._link.config.item[lib.config.mode_config.guozhan.aozhan_bgm]; + if(!Array.isArray(_status.aozhanBGMToRemove)) return; + const menu=this._link.menu; + for(let i=0;i=190|| - dialog._place_text.firstChild.offsetHeight>=30){ - dialog._place_text.style.textAlign='left'; + if(dialog._place_text.firstChild.offsetWidth>=190||dialog._place_text.firstChild.offsetHeight>=30){ dialog._place_text.style.marginLeft='14px'; + dialog._place_text.style.marginRight='14px'; + dialog._place_text.style.textAlign='left'; + dialog._place_text.style.width='calc(100% - 28px)'; } } if(e.touches&&e.touches[0]){ @@ -7068,93 +7257,75 @@ this.classList.remove('removing'); return this; }; - HTMLDivElement.prototype.setBackground=function(name,type,ext,subfolder){ - if(!name) return; - var src; - if(ext=='noskin'){ - ext='.jpg'; - } - ext=ext||'.jpg'; - subfolder=subfolder||'default' - if(type){ - var dbimage=null,extimage=null,modeimage=null; - var nameinfo; - var gzbool=false; - var mode=get.mode(); - if(type=='character'){ - if(lib.characterPack['mode_'+mode]&&lib.characterPack['mode_'+mode][name]){ - if(mode=='guozhan'){ + Object.defineProperty(HTMLDivElement.prototype,'setBackground',{ + configurable:true, + enumerable:false, + writable:true, + value:function(name,type,ext,subfolder){ + if(!name) return; + let src; + if(ext=='noskin') ext='.jpg'; + ext=ext||'.jpg'; + subfolder=subfolder||'default'; + if(type){ + let dbimage=null,extimage=null,modeimage=null,nameinfo,gzbool=false; + const mode=get.mode(); + if(type=='character'){ + if(lib.characterPack[`mode_${mode}`]&&lib.characterPack[`mode_${mode}`][name]) if(mode=='guozhan'){ nameinfo=lib.character[name]; - if(name.indexOf('gz_shibing')==0){ - name=name.slice(3,11); - } + if(name.indexOf('gz_shibing')==0) name=name.slice(3,11); else{ - if(lib.config.mode_config.guozhan.guozhanSkin&&lib.character[name]&&lib.character[name][4].contains('gzskin')) gzbool=true; + if(lib.config.mode_config.guozhan.guozhanSkin&&lib.character[name]&&lib.character[name][4].contains('gzskin')) gzbool=true; name=name.slice(3); } } - else{ - modeimage=mode; + else modeimage=mode; + else if(lib.character[name]) nameinfo=lib.character[name]; + else if(lib.config.show_extensionimage){ + const pack=Object.keys(lib.characterPack).find(pack=>Object.keys(lib.characterPack[pack]).contains(name)); + if(pack) nameinfo=lib.characterPack[pack][name]; + } + else if(name.indexOf('::')!=-1){ + name=name.split('::'); + modeimage=name[0]; + name=name[1]; } } - else if(lib.character[name]){ - nameinfo=lib.character[name]; - } - else if(lib.config.show_extensionimage){ - var pack=Object.keys(lib.characterPack).find(pack => Object.keys(lib.characterPack[pack]).contains(name)); - if(pack) nameinfo=lib.characterPack[pack][name]; - } - else if(name.indexOf('::')!=-1){ - name=name.split('::'); - modeimage=name[0]; - name=name[1]; - } - } - if(!modeimage&&nameinfo&&nameinfo[4]){ - for(var i=0;i{ + const font=pack.font[value]; + appearenceConfig.name_font.item[value]=font; + appearenceConfig.identity_font.item[value]=font; + appearenceConfig.cardtext_font.item[value]=font; + appearenceConfig.global_font.item[value]=font; + fontSheet.insertRule(`@font-face {font-family: '${value}'; src: local('${font}'), url('${lib.assetURL}font/${value}.woff2');}`,0); + if(suitsFont) fontSheet.insertRule(`@font-face {font-family: '${value}'; src: local('${font}'), url('${lib.assetURL}font/suits.woff2');}`,0); + }); + if(suitsFont) fontSheet.insertRule(`@font-face {font-family: 'Suits'; src: local('Noname Suit'), url('${lib.assetURL}font/suits.woff2');}`,0); + appearenceConfig.cardtext_font.item.default='默认'; + appearenceConfig.global_font.item.default='默认'; } var ua=navigator.userAgent.toLowerCase(); @@ -7901,32 +8074,44 @@ } } } - var loadPack=function(){ - var toLoad=lib.config.all.cards.length+lib.config.all.characters.length+1; - var packLoaded=function(){ + const loadPack=()=>{ + let toLoad=lib.config.all.cards.length+lib.config.all.characters.length+1; + if(_status.jsExt) toLoad+=_status.jsExt.length; + const packLoaded=()=>{ toLoad--; - if(toLoad==0){ - if(_status.windowLoaded){ - delete _status.windowLoaded; - lib.init.onload(); - } - else{ - _status.packLoaded=true; - } + if(toLoad) return; + if(_status.windowLoaded){ + delete _status.windowLoaded; + lib.init.onload(); } + else _status.packLoaded=true; }; - if(localStorage.getItem(lib.configprefix+'playback')){ + if(localStorage.getItem(`${lib.configprefix}playback`)){ toLoad++; - lib.init.js(lib.assetURL+'mode',lib.config.mode,packLoaded,packLoaded); + lib.init.js(`${lib.assetURL}mode`,lib.config.mode,packLoaded,packLoaded); } - else if((localStorage.getItem(lib.configprefix+'directstart')||!show_splash)&& - lib.config.all.mode.indexOf(lib.config.mode)!=-1){ + else if((localStorage.getItem(`${lib.configprefix}directstart`)||!show_splash)&&lib.config.all.mode.indexOf(lib.config.mode)!=-1){ toLoad++; - lib.init.js(lib.assetURL+'mode',lib.config.mode,packLoaded,packLoaded); - } - lib.init.js(lib.assetURL+'card',lib.config.all.cards,packLoaded,packLoaded); - lib.init.js(lib.assetURL+'character',lib.config.all.characters,packLoaded,packLoaded); - lib.init.js(lib.assetURL+'character','rank',packLoaded,packLoaded); + lib.init.js(`${lib.assetURL}mode`,lib.config.mode,packLoaded,packLoaded); + } + lib.init.js(`${lib.assetURL}card`,lib.config.all.cards,packLoaded,packLoaded); + lib.init.js(`${lib.assetURL}character`,lib.config.all.characters,packLoaded,packLoaded); + lib.init.js(`${lib.assetURL}character`,'rank',packLoaded,packLoaded); + if(!_status.jsExt) return; + const loadJSExt=(jsExt,pathArray,nameArray,index)=>{ + if(!pathArray&&!nameArray){ + lib.init.js(jsExt.path,jsExt.name,packLoaded,packLoaded); + return; + } + if(typeof index!='number') index=0; + if(pathArray&&index>=jsExt.path.length||nameArray&&index>=jsExt.name.length) return; + const path=pathArray?jsExt.path[index]:jsExt.path,name=nameArray?jsExt.name[index]:jsExt.name,jsExtLoaded=()=>{ + loadJSExt(jsExt,pathArray,nameArray,index+1); + packLoaded(); + }; + lib.init.js(path,name,jsExtLoaded,jsExtLoaded); + }; + _status.jsExt.forEach(value=>loadJSExt(value,Array.isArray(value.path),Array.isArray(value.name))); // if(lib.device!='ios'&&lib.config.enable_pressure) lib.init.js(lib.assetURL+'game','pressure'); }; @@ -8096,10 +8281,8 @@ ui.backgroundMusic.pause(); } }); - document.addEventListener("resume", function(){ - if(ui.backgroundMusic){ - ui.backgroundMusic.play(); - } + document.addEventListener("resume", ()=>{ + if(ui.backgroundMusic) Promise.resolve(ui.backgroundMusic.play()).catch(()=>void 0); }); document.addEventListener("backbutton", function(){ if(ui.arena&&ui.arena.classList.contains('menupaused')){ @@ -8609,6 +8792,11 @@ } }, onload:function(){ + const libOnload=lib.onload; + delete lib.onload; + while(libOnload.length){ + libOnload.shift()(); + } ui.updated(); game.documentZoom=game.deviceZoom; if(game.documentZoom!=1){ @@ -9473,55 +9661,46 @@ } return style; }, - js:function(path,file,onload,onerror){ - if(path[path.length-1]=='/'){ - path=path.slice(0,path.length-1); - } - if(path==lib.assetURL+'mode'&&lib.config.all.stockmode.indexOf(file)==-1){ - lib.init['setMode_'+file](); + //在扩展的precontent中调用,用于加载扩展必需的JS文件。 + //If any of the parameters is an Array, corresponding files will be loaded in order + //如果任意参数为数组,则按顺序加载加载相应的文件 + jsForExtension:(path,name)=>{ + if(!_status.jsExt) _status.jsExt=[]; + _status.jsExt.add({ + path:path, + name:name + }); + }, + js:(path,file,onload,onerror)=>{ + if(path[path.length-1]=='/') path=path.slice(0,path.length-1); + if(path==`${lib.assetURL}mode`&&lib.config.all.stockmode.indexOf(file)==-1){ + lib.init[`setMode_${file}`](); onload(); return; } if(Array.isArray(file)){ - for(var i=0;ilib.init.js(path,value,onload,onerror)); + return; } + let script_src; + if(!file) script_src=path; + else script_src=`${path}/${file}.js`; + if(path.indexOf('http')==0) script_src+=`?rand=${get.id()}`; + else if(game.readFile&&lib.config.fuck_sojson&&script_src.includes('extension')!=-1&&script_src.indexOf(lib.assetURL)==0){ + const path_to_read=script_src.slice(lib.assetURL.length); + game.readFileAsText(path_to_read,result=>{ + if(result.includes('sojson')||result.includes('jsjiami')||result.includes('var _0x')) alert(`检测到您安装了使用免费版sojson进行加密的扩展。请谨慎使用这些扩展,避免游戏数据遭到破坏。\n扩展文件:${path_to_read}`); + },()=>void 0); + } + const script=document.createElement('script'); + script.src=script_src; + if(path.indexOf('http')==0) script.addEventListener('load',()=>script.remove()); + document.head.appendChild(script); + if(typeof onload=='function'){ + script.addEventListener('load',onload); + script.addEventListener('error',onerror); + } + return script; }, req:function(str,onload,onerror,master){ var sScriptURL; @@ -10600,7 +10779,7 @@ eight:'八', nine:'九', ten:'十', - _chongzhu:'重铸', + _recasting:'重铸', _lianhuan:'连环', _lianhuan2:'连环', _kamisha:'神杀', @@ -10700,25 +10879,54 @@ emptyEvent:function(){ event.trigger(event.name); }, + //Gift + //赠予 + gift:()=>{ + 'step 0' + event.num=0; + 'step 1' + if(num{ 'step 0' game.log(player,'重铸了',cards); - if(typeof event.recastingLose=='function') event.recastingLostCards=event.recastingLose(player,cards); + if(typeof event.recastingLose!='function') return; + event.trigger('recastingLose'); + event.recastingLose(player,cards); + event.trigger('recastingLost'); + event.recastingLosingEvents.push(...event.next.filter(value=>value.name!='arrangeTrigger')); 'step 1' event.trigger('recast'); 'step 2' if(typeof event.recastingGain!='function') return; - event.recastingGainedCards=event.recastingGain(player,cards); - if(get.itemtype(event.recastingGainedCards)=='card') event.recastingGainedCards=[event.recastingGainedCards]; - 'step 3' - event.result=[]; - if(get.itemtype(event.recastingGainedCards)=='cards') event.result.addArray(event.recastingGainedCards); - if(get.itemtype(result.cards)=='card') event.result.push(result.cards); - else if(get.itemtype(result.cards)=='cards') event.result.addArray(result.cards); - if(get.itemtype(result)=='card') event.result.push(result); - else if(get.itemtype(result)=='cards') event.result.addArray(result); + event.trigger('recastingGain'); + event.recastingGain(player,cards); + event.trigger('recastingGained'); + event.recastingGainingEvents.push(...event.next.filter(value=>value.name!='arrangeTrigger')); }, //装备栏相关 disableEquip:function(){ @@ -10928,7 +11136,7 @@ },subtype); player.$equip(card); game.addVideo('equip',player,get.cardInfo(card)); - game.log(player,'装备了',card); + if(event.log!=false) game.log(player,'装备了',card); if(event.updatePile) game.updateRoundNumber(); "step 6" var info=get.info(card,false); @@ -10947,7 +11155,7 @@ next.player=player; next.card=card; } - if(info.equipDelay!='false') game.delayx(); + if(info.equipDelay!=false) game.delayx(); } delete player.equiping; if(event.delay){ @@ -11190,10 +11398,7 @@ game.resume(); _status.imchoosing=false; if(roundmenu) ui.roundmenu.style.display=''; - if(ui.backgroundMusic){ - var promise=ui.backgroundMusic.play(); - if(promise) promise.catch(()=>void 0); - } + if(ui.backgroundMusic) Promise.resolve(ui.backgroundMusic.play()).catch(()=>void 0); hitsound_audio.remove(); },1000); }; @@ -11308,7 +11513,7 @@ combo++; max_combo=Math.max(combo,max_combo); hitsound_audio.currentTime=0; - if(hitsound_audio.paused) hitsound_audio.play(); + if(hitsound_audio.paused) Promise.resolve(hitsound_audio.play()).catch(()=>void 0); break; } }; @@ -11382,10 +11587,7 @@ if(dialog){ dialog.close(); } - if(ui.backgroundMusic){ - var promise=ui.backgroundMusic.play(); - if(promise) promise.catch(()=>void 0); - } + if(ui.backgroundMusic) Promise.resolve(ui.backgroundMusic.play()).catch(()=>void 0); },event.videoId,event.time); var result=event.result||result; event.result=result; @@ -14004,6 +14206,172 @@ next.getlx=false; } }, + chooseToCompareMeanwhile:function(){ + 'step 0' + if(player.countCards('h')==0){ + event.result={cancelled:true,bool:false} + event.finish(); + return; + } + for(var i=0; ievent.maxNum){ + event.maxNum=i[1]; + event.winner=i[0]; + } + else if(event.winner&&i[1]==event.maxNum&&i[0]!=event.winner){ + event.winner=null; + } + } + 'step 8' + event.iwhile++; + event.goto(6); + 'step 9' + var player=event.tempplayer; + event.player=player; + delete event.tempplayer; + var str='无人拼点成功'; + if(event.winner){ + event.result.winner=event.winner; + str=get.translation(event.winner)+'拼点成功'; + game.log(event.winner,'拼点成功'); + event.winner.popup('胜'); + } else game.log('#b无人','拼点成功'); + var list=[player].addArray(targets); + list.remove(event.winner); + for(var i of list){ + i.popup('负'); + } + if(str){ + game.broadcastAll(function(str){ + var dialog=ui.create.dialog(str); + dialog.classList.add('center'); + setTimeout(function(){ + dialog.close(); + },1000); + },str); + } + game.delay(3); + 'step 10' + game.broadcastAll(ui.clear); + 'step 11' + event.cards.add(event.card1); + }, chooseToCompareMultiple:function(){ "step 0" if(player.countCards('h')==0){ @@ -14093,8 +14461,11 @@ num1:[], num2:[], }; - game.log(player,'的拼点牌为',event.card1); "step 3" + event.trigger('compareCardShowBefore'); + "step 4" + game.log(player,'的拼点牌为',event.card1); + "step 5" if(event.iwhile1){ @@ -16165,7 +16533,7 @@ } return null; } - "step 4" + "step 5" if(event.all_excluded) return; if(!event.triggeredTargets1) event.triggeredTargets1=[]; var target=event.getTriggerTarget(targets,event.triggeredTargets1); @@ -16189,7 +16557,7 @@ if(event.forceDie) next.forceDie=true; event.redo(); } - "step 5" + "step 6" if(event.all_excluded) return; if(!event.triggeredTargets2) event.triggeredTargets2=[]; var target=event.getTriggerTarget(targets,event.triggeredTargets2); @@ -16213,7 +16581,7 @@ if(event.forceDie) next.forceDie=true; event.redo(); } - "step 6" + "step 7" var info=get.info(card,false); if(!info.nodelay&&event.animate!=false){ if(event.delayx!==false){ @@ -16226,7 +16594,7 @@ } } } - "step 7" + "step 8" if(event.all_excluded) return; if(!event.triggeredTargets3) event.triggeredTargets3=[]; var target=event.getTriggerTarget(targets,event.triggeredTargets3); @@ -16250,7 +16618,7 @@ if(event.forceDie) next.forceDie=true; event.redo(); } - "step 8" + "step 9" if(event.all_excluded) return; if(!event.triggeredTargets4) event.triggeredTargets4=[]; var target=event.getTriggerTarget(targets,event.triggeredTargets4); @@ -16277,7 +16645,7 @@ } event.redo(); } - "step 9" + "step 10" if(event.all_excluded) return; event.effectedCount++; event.num=0; @@ -16318,7 +16686,7 @@ next.addedTargets=event.addedTargets; if(event.forceDie) next.forceDie=true; } - "step 10" + "step 11" if(event.all_excluded) return; var info=get.info(card,false); if(num==0&&targets.length>1){ @@ -16382,13 +16750,13 @@ game.delayx(0.5); } } - "step 11" + "step 12" if(event.all_excluded) return; if(!get.info(event.card,false).multitarget&&numtarget.hp?-1:0; + if(target.hasSkillTag('nogain')) return 0; + return Math.max(1,get.value(card,this)-get.value(card,target)); + }, + getGiftEffect:function(card,target){ + return this.getGiftAIResultTarget(card,target)*get.attitude(this,target); + }, //Recast //重铸 recast:function(cards,recastingLose,recastingGain){ const recast=game.createEvent('recast'); recast.player=this; - if(get.itemtype(cards)=='card') recast.cards=[cards]; - else if(get.itemtype(cards)=='cards'&&cards.length) recast.cards=cards; + const isArray=Array.isArray(cards); + if(cards&&!isArray) recast.cards=[cards]; + else if(isArray&&cards.length) recast.cards=cards; else _status.event.next.remove(recast); - if(typeof recastingLose!='function') recastingLose=(player,cards)=>player.loseToDiscardpile(cards).set("log",false).cards; + if(typeof recastingLose!='function') recastingLose=(player,cards)=>player.loseToDiscardpile(cards).log=false; recast.recastingLose=recastingLose; + recast.recastingLosingEvents=[]; if(typeof recastingGain!='function') recastingGain=(player,cards)=>player.draw(cards.length).log=false; recast.recastingGain=recastingGain; + recast.recastingGainingEvents=[]; recast.setContent('recast'); recast._args=Array.from(arguments); return recast; }, //Check if the player can recast the card - //检查角色是否能重铸此牌 + //检测角色是否能重铸此牌 canRecast:function(card,source,strict){ - const cardRecastable=lib.filter.cardRecastable(card,this,source,strict); - if(cardRecastable!='unchanged') return cardRecastable; - if(get.position(card)!='h') return false; - const info=get.info(card); - return typeof info.chongzhu=='function'?info.chongzhu(_status.event,this):info.chongzhu; + return lib.filter.cardRecastable(card,this,source,strict); }, //装备栏相关 //判断一名角色的某个区域是否被废除 @@ -21785,7 +22194,7 @@ } if(result.card||!result.skill){ result.used=result.card||result.cards[0]; - var next=this.useCard(result.card,result.cards,result.targets,result.skill); + var next=this.useCard(result.used,result.cards,result.targets,result.skill); next.oncard=event.oncard; next.respondTo=event.respondTo; if(event.addCount===false){ @@ -22308,7 +22717,7 @@ if(!position) position=ui.discardPile; if(!key) key='cards'; var cards=[],event=this; - game.getGlobalHistory('cardMove',function(evt){ + game.checkGlobalHistory('cardMove',function(evt){ if(evt.name!='lose'||evt.position!=position||evt.getParent()!=event) return; if(player&&player!=evt.player) return; cards.addArray(evt[key]); @@ -22327,7 +22736,7 @@ cards:[], cards2:[], }; - player.getHistory('lose',function(evt){ + player.checkHistory('lose',function(evt){ if(evt.parent==that){ map.hs.addArray(evt.hs); map.es.addArray(evt.es); @@ -22390,7 +22799,7 @@ if(!position) position=ui.discardPile; if(!key) key='cards'; var cards=[],event=this; - game.getGlobalHistory('cardMove',function(evt){ + game.checkGlobalHistory('cardMove',function(evt){ if(evt.name!='lose'||evt.position!=position||evt.getParent()!=event) return; if(player&&player!=evt.player) return; cards.addArray(evt[key]); @@ -22409,7 +22818,7 @@ cards:[], cards2:[], }; - player.getHistory('lose',function(evt){ + player.checkHistory('lose',function(evt){ if(evt.parent==that){ map.hs.addArray(evt.hs); map.es.addArray(evt.es); @@ -22641,7 +23050,7 @@ return next; }, changeHp:function(num,popup){ - var next=game.createEvent('changeHp',false); + var next=game.createEvent('changeHp'); next.num=num; if(popup!=undefined) next.popup=popup; next.player=this; @@ -22873,7 +23282,7 @@ if(!position) position=ui.discardPile; if(!key) key='cards'; var cards=[],event=this; - game.getGlobalHistory('cardMove',function(evt){ + game.checkGlobalHistory('cardMove',function(evt){ if(evt.name!='lose'||evt.position!=position||evt.getParent()!=event) return; if(player&&player!=evt.player) return; cards.addArray(evt[key]); @@ -22892,7 +23301,7 @@ cards:[], cards2:[], }; - player.getHistory('lose',function(evt){ + player.checkHistory('lose',function(evt){ if(evt.parent==that){ map.hs.addArray(evt.hs); map.es.addArray(evt.es); @@ -22927,7 +23336,7 @@ if(!position) position=ui.discardPile; if(!key) key='cards'; var cards=[],event=this; - game.getGlobalHistory('cardMove',function(evt){ + game.checkGlobalHistory('cardMove',function(evt){ if(evt.name!='lose'||evt.position!=position||evt.getParent()!=event) return; if(player&&player!=evt.player) return; cards.addArray(evt[key]); @@ -22946,7 +23355,7 @@ cards:[], cards2:[], }; - player.getHistory('lose',function(evt){ + player.checkHistory('lose',function(evt){ if(evt.parent==that){ map.hs.addArray(evt.hs); map.es.addArray(evt.es); @@ -24510,25 +24919,47 @@ if(!key) return this.actionHistory[this.actionHistory.length-1]; if(!filter) return this.actionHistory[this.actionHistory.length-1][key]; else{ - var history=this.getHistory(key).slice(0); - if(last) history=history.slice(0,history.indexOf(last)+1); - for(var i=0;i{ + if(index>lastIndex) return false; + return filter(event); + }) + } + return history.filter(filter); + } + }, + checkHistory:function(key,filter,last){ + if(!key||!filter) return; + else{ + const history=this.getHistory(key); + if(last){ + const lastIndex=history.indexOf(last); + history.forEach((event,index)=>{ + if(index>lastIndex) return false; + filter(event); + }) + } + else{ + history.forEach(filter); } - return history; } }, hasHistory:function(key,filter,last){ - var history=this.getHistory(key).slice(0); - if(last) history=history.slice(0,history.indexOf(last)+1); - for(var i=0;i{ + if(index>lastIndex) return false; + return filter(event); + }) } - return false; + return history.some(filter); }, getLastHistory:function(key,filter,last){ - var history=false; - for(var i=this.actionHistory.length-1;i>=0;i--){ + let history=false; + for(let i=this.actionHistory.length-1;i>=0;i--){ if(this.actionHistory[i].isMe){ history=this.actionHistory[i];break; } @@ -24537,45 +24968,69 @@ if(!key) return history; if(!filter) return history[key]; else{ - history=history.slice(0); - if(last) history=history.slice(0,history.indexOf(last)+1); - for(var i=0;i{ + if(index>lastIndex) return false; + return filter(event); + }) } - return history; + return history.filter(filter); } }, + checkAllHistory:function(key,filter,last){ + if(!key||!filter) return; + this.actionHistory.forEach((value)=>{ + let history=value[key]; + if(last&&history.includes(last)){ + const lastIndex=history.indexOf(last); + history.forEach((event,index)=>{ + if(index>lastIndex) return false; + return filter(event); + }); + } + else{ + history.forEach(filter); + } + }); + }, getAllHistory:function(key,filter,last){ - var list=[]; - var all=this.actionHistory; - for(var j=0;j{ + if(!key||!value[key]){ + history.push(value); } else{ - if(!filter) list.addArray(all[j][key]); - else{ - var history=all[j][key].slice(0); - if(last) history=history.slice(0,history.indexOf(last)+1); - for(var i=0;i{ + if(index>lastIndex) return false; + return filter(event); + }); + } + return history.filter(filter); } - return list; + return history; }, hasAllHistory:function(key,filter,last){ - var list=[]; - var all=this.actionHistory; - for(var j=0;j{ + let history=value[key]; + if(last&&history.includes(last)){ + const lastIndex=history.indexOf(last); + if(history.some(function(event,index){ + if(index>lastIndex) return false; + return filter(event); + })) return true; } - } - return false; + else{ + if(history.some(filter)) return true; + } + return false; + }) }, getLastUsed:function(num){ if(typeof num!='number') num=0; @@ -24863,7 +25318,7 @@ isFriendOf:function(player){ if(get.mode()=='guozhan'){ if(this==player) return true; - if(this.storage.yexinjia_friend==player||player.storage.yexinjia_friend==this) return true; + if(this.getStorage('yexinjia_friend').includes(player)||player.getStorage('yexinjia_friend').includes(this)) return true; if(this.identity=='unknown'||this.identity=='ye') return false; if(player.identity=='unknown'||player.identity=='ye') return false; return this.identity==player.identity; @@ -25063,14 +25518,7 @@ }, needsToDiscard:function(num){ if(typeof num!='number') num=0; - var hs=this.getCards('h'); - num+=hs.length; - for(var i=0;i!this.canIgnoreHandcard(card))-this.getHandcardLimit()); }, distanceTo:function(target,method){ return get.distance(this,target,method); @@ -27326,6 +27774,24 @@ finish:function(){ this.finished=true; }, + putTempCache:function(key1,key2,value){ + if(!this._tempCache){ + this._tempCache = {}; + } + if(!this._tempCache[key1]){ + this._tempCache[key1] = {}; + } + this._tempCache[key1][key2] = value; + }, + getTempCache:function(key1,key2){ + if(!this._tempCache){ + return undefined; + } + if(!this._tempCache[key1]){ + return undefined; + } + return this._tempCache[key1][key2]; + }, cancel:function(arg1,arg2,notrigger){ this.untrigger.call(this,arguments); this.finish(); @@ -28327,11 +28793,28 @@ all:function(){ return true; }, + //Check if the card does not count toward the player's hand limit + //检测此牌是否不计入此角色的手牌上限 + ignoredHandcard:(card,player)=>game.checkMod(card,player,false,'ignoredHandcard',player), + //Check if the card is giftable + //检测此牌是否可赠予 + cardGiftable:(card,player,target,strict)=>{ + const mod=game.checkMod(card,player,target,'unchanged','cardGiftable',player); + if(!mod||strict&&(mod=='unchanged'&&(get.position(card)!='h'||!get.cardtag(card,'gifts'))||player==target)) return false; + return get.type(card,false)!='equip'||target.canEquip(card,true); + }, //Check if the card is recastable //检查此牌是否可重铸 - cardRecastable:(card,player,source,raw)=>{ + cardRecastable:(card,player,source,strict)=>{ if(typeof player=='undefined') player=get.owner(card); - return game.checkMod(card,player,source,!raw||'unchanged','cardRecastable',player); + const mod=game.checkMod(card,player,source,'unchanged','cardRecastable',player); + if(!mod) return false; + if(strict&&mod=='unchanged'){ + if(get.position(card)!='h') return false; + const info=get.info(card),recastable=info.recastable||info.chongzhu; + return Boolean(typeof recastable=='function'?recastable(_status.event,player):recastable); + } + return true; }, //装备栏相关 canBeReplaced:function(card,player){ @@ -28532,7 +29015,7 @@ } var num=info.usable; if(typeof num=='function') num=num(card,player); - num=game.checkMod(card,player,num,event,'cardUsable',player); + num=game.checkMod(card,player,num,'cardUsable',player); if(typeof num!='number') return true; else return(player.countUsed(card)player.hasCard(card=>lib.skill._chongzhu.filterCard(card,player),'he'), + filter:(event,player)=>player.hasCard(card=>lib.skill._recasting.filterCard(card,player),lib.skill._recasting.position), position:'he', filterCard:(card,player)=>player.canRecast(card,null,true), discard:false, lose:false, delay:false, - content:function(){ + content:()=>{ player.recast(cards,null,(player,cards)=>{ - var numberOfCardsToDraw=cards.length, cardsToGain=[]; + var numberOfCardsToDraw=cards.length; cards.forEach(value=>{ if(lib.config.mode=='stone'&&_status.mode=='deck'&&!player.isMin()&&get.type(value).indexOf('stone')==0){ var stonecard=get.stonecard(1,player.career); if(stonecard.length){ numberOfCardsToDraw-=stonecard.length; - var card=game.createCard(stonecard.randomGet()); - player.gain(card,'draw'); - cardsToGain.push(card); + player.gain(game.createCard(stonecard.randomGet()),'draw'); } else player.draw({ drawDeck:1 @@ -29980,21 +30467,16 @@ var libCard=get.libCard(info=>info.subtype=='spell_silver'); if(!libCard.length) return; numberOfCardsToDraw--; - var card=game.createCard(libCard.randomGet()); - player.gain(card,'draw'); - cardsToGain.push(card); + player.gain(game.createCard(libCard.randomGet()),'draw'); } else if(get.subtype(value)=='spell_silver'){ var libCard=get.libCard(info=>info.subtype=='spell_bronze'); if(!libCard.length) return; numberOfCardsToDraw--; - var card=game.createCard(libCard.randomGet()); - player.gain(card,'draw'); - cardsToGain.push(card); + player.gain(game.createCard(libCard.randomGet()),'draw'); } }); if(numberOfCardsToDraw) player.draw(numberOfCardsToDraw).log=false; - return cardsToGain; }); }, ai:{ @@ -30051,6 +30533,71 @@ player.link(); if(trigger.getParent().notLink()) trigger.getParent().lianhuanable=true; } + }, + //Deprecated skills + _chongzhu:{ + get filter(){ + return lib.skill._recasting.filter; + }, + set filter(filter){ + lib.skill._recasting.filter=filter; + }, + get filterCard(){ + return lib.skill._recasting.filterCard; + }, + set filterCard(filterCard){ + lib.skill._recasting.filterCard=filterCard; + }, + get content(){ + return lib.skill._recasting.content; + }, + set content(content){ + lib.skill._recasting.content=content; + }, + get ai(){ + return lib.skill._recasting.ai; + }, + set ai(ai){ + lib.skill._recasting.ai=ai; + } + }, + _yongjian_zengyu:{ + get filter(){ + return lib.skill._gifting.filter; + }, + set filter(filter){ + lib.skill._gifting.filter=filter; + }, + get filterCard(){ + return lib.skill._gifting.filterCard; + }, + set filterCard(filterCard){ + lib.skill._gifting.filterCard=filterCard; + }, + get filterTarget(){ + return lib.skill._gifting.filterTarget; + }, + set filterTarget(filterTarget){ + lib.skill._gifting.filterTarget=filterTarget; + }, + get check(){ + return lib.skill._gifting.check; + }, + set check(check){ + lib.skill._gifting.check=check; + }, + get content(){ + return lib.skill._gifting.content; + }, + set content(content){ + lib.skill._gifting.content=content; + }, + get ai(){ + return lib.skill._gifting.ai; + }, + set ai(ai){ + lib.skill._gifting.ai=ai; + } } }, character:{}, @@ -31145,6 +31692,19 @@ jin:'thunder', ye:'thunder', }, + lineColor:new Map([ + ['fire',[255,146,68]], + ['yellow',[255,255,122]], + ['blue',[150,202,255]], + ['green',[141,255,216]], + ['ice',[59,98,115]], + ['thunder',[141,216,255]], + ['kami',[90,118,99]], + ['white',[255,255,255]], + ['poison',[104,221,127]], + ['brown',[195,161,223]], + ['legend',[233,131,255]] + ]), phaseName:['phaseZhunbei','phaseJudge','phaseDraw','phaseUse','phaseDiscard','phaseJieshu'], quickVoice:[ '我从未见过如此厚颜无耻之人!', @@ -31172,7 +31732,58 @@ '妹子,交个朋友吧', ], }; - var game={ + const game={ + //Yingbian + //应变 + yingbianEffect:function(event,content){ + const yingbianEffect=game.createEvent('yingbianEffect'); + yingbianEffect.player=event.player; + yingbianEffect.card=event.card; + yingbianEffect._trigger=event; + yingbianEffect.setContent(content); + yingbianEffect._args=Array.from(arguments); + return yingbianEffect; + }, + setYingbianConditionColor:(yingbianCondition,color)=>game.broadcastAll((yingbianCondition,color)=>lib.yingbian.condition.color.set(yingbianCondition,color),yingbianCondition,color), + setComplexYingbianCondition:(yingbianCondition,condition)=>game.broadcastAll((yingbianCondition,condition)=>lib.yingbian.condition.complex.set(yingbianCondition,condition),yingbianCondition,condition), + setSimpleYingbianCondition:(yingbianCondition,condition)=>game.broadcastAll((yingbianCondition,condition)=>lib.yingbian.condition.simple.set(yingbianCondition,condition),yingbianCondition,condition), + setYingbianEffect:(yingbianEffect,effect)=>game.broadcastAll((yingbianEffect,effect)=>lib.yingbian.effect.set(yingbianEffect,effect),yingbianEffect,effect), + setYingbianPrompt:(yingbian,prompt)=>game.broadcastAll((yingbian,prompt)=>lib.yingbian.prompt.set(yingbian,prompt),yingbian,prompt), + //Add a background music to the config option + //在设置选项中添加一首背景音乐 + addBackgroundMusic:(link,musicName,aozhan)=>{ + const backgroundMusicSetting=ui[aozhan?'aozhan_bgm':'background_music_setting'],menu=backgroundMusicSetting._link.menu,config=backgroundMusicSetting._link.config; + if(typeof musicName!='string') musicName=link; + if(aozhan) lib.mode.guozhan.config.aozhan_bgm.item[link]=musicName; + else lib.config.all.background_music.add(link); + config.item[link]=musicName; + const textMenu=ui.create.div('',musicName,menu,function(){ + const node=this.parentNode._link,config=node._link.config; + node._link.current=this.link; + const tmpName=node.lastChild.innerHTML; + node.lastChild.innerHTML=config.item[this._link]; + if(config.onclick&&config.onclick.call(node,this._link,this)===false) node.lastChild.innerHTML=tmpName; + if(config.update) config.update(); + },menu.childElementCount-2); + textMenu._link=link; + config.updatex.call(backgroundMusicSetting,[]); + }, + //Remove a background music from the config option + //从设置选项中移除一首背景音乐 + removeBackgroundMusic:(link,aozhan)=>{ + if(aozhan){ + if(['disabled','random'].includes(link)) return; + delete lib.mode.guozhan.config.aozhan_bgm.item[link]; + if(!Array.isArray(_status.aozhanBGMToRemove)) _status.aozhanBGMToRemove=[]; + _status.aozhanBGMToRemove.add(link); + } + else{ + if(['music_off','music_custom','music_random'].includes(link)) return; + lib.config.all.background_music.remove(link); + } + const backgroundMusicSetting=ui[aozhan?'aozhan_bgm':'background_music_setting'],config=backgroundMusicSetting._link.config; + config.updatex.call(backgroundMusicSetting,[]); + }, updateBackground:function(){ var background=(_status.tempBackground||lib.config.image_background); ui.background.delete(); @@ -31190,7 +31801,10 @@ } document.body.insertBefore(ui.background,document.body.firstChild); - if(background=='default'){ + if(background.indexOf('ext:')==0){ + ui.background.setBackgroundImage('extension/'+background.slice(4)); + } + else if(background=='default'){ ui.background.animate('start'); ui.background.style.backgroundImage="none"; } @@ -31213,6 +31827,8 @@ ui.background.style.backgroundSize='cover'; ui.background.style.backgroundPosition='50% 50%'; }, + //Generate a beatmap using the given BPM, beats, and offset + //用给定的BPM、节拍和偏移生成谱面 generateBeatmapTimeleap:(bpm,beats,offset)=>beats.map(value=>Math.round(value*60000/bpm+(offset||0))), updateRenku:function(){ game.broadcast(function(renku){ @@ -31229,7 +31845,7 @@ if(!position) position=ui.discardPile; if(!key) key='cards'; var cards=[],event=this; - game.getGlobalHistory('cardMove',function(evt){ + game.checkGlobalHistory('cardMove',function(evt){ if(evt.name!='lose'||evt.position!=position||evt.getParent()!=event) return; if(player&&player!=evt.player) return; cards.addArray(evt[key]); @@ -31248,7 +31864,7 @@ cards:[], cards2:[], }; - player.getHistory('lose',function(evt){ + player.checkHistory('lose',function(evt){ if(evt.parent==that){ map.hs.addArray(evt.hs); map.es.addArray(evt.es); @@ -31264,7 +31880,7 @@ next.getg=function(player){ var that=this; var cards=[]; - player.getHistory('gain',function(evt){ + player.checkHistory('gain',function(evt){ if(evt.parent==that){ cards.addArray(evt.cards); } @@ -31284,35 +31900,76 @@ if(get.mode()!='chess'&&rank.junk.contains(name)) return 'junk'; return 'common'; }, - getGlobalHistory:function(key,filter){ + checkGlobalHistory:function(key,filter,last){ if(!key) return _status.globalHistory[_status.globalHistory.length-1]; if(!filter) return _status.globalHistory[_status.globalHistory.length-1][key]; else{ - var history=game.getGlobalHistory(key).slice(0); - for(var i=0;i{ + if(index>lastIndex) return false; + return filter(event); + }); + } + else{ + history.forEach(filter); } - return history; } }, - getAllGlobalHistory:function(key,filter){ - var list=[]; - var all=_status.globalHistory; - for(var j=0;j{ + if(index>lastIndex) return false; + return filter(event); + }) } - else{ - if(!filter) list.addArray(all[j][key]); + return history.filter(filter); + } + }, + checkAllGlobalHistory:function(key,filter,last){ + if(!key||!filter) return; + _status.globalHistory.forEach(value=>{ + if(value[key]){ + if(last&&value[key].includes(last)){ + const lastIndex=value[key].indexOf(last); + value[key].filter((event,index)=>{ + if(index>lastIndex) return false; + return filter(event); + }); + } else{ - var history=all[j][key].slice(0); - for(var i=0;i{ + if(!key||!value[key]){ + history.push(value); + } + else{ + history.push(...value[key]); + } + }) + if(filter){ + if(last){ + const lastIndex=history.indexOf(last); + return history.filter(function(event,index){ + if(index>lastIndex) return false; + return filter(event); + }); + } + return history.filter(filter); } - return list; + return history; }, cardsDiscard:function(cards){ var type=get.itemtype(cards); @@ -31918,7 +32575,7 @@ }; //Some browsers do not support "autoplay", so "oncanplay" listening has been added audio.oncanplay=function(){ - this.play(); + Promise.resolve(this.play()).catch(()=>void 0); }; ui.window.appendChild(audio); return audio; @@ -32029,7 +32686,7 @@ }; //Some browsers do not support "autoplay", so "oncanplay" listening has been added audio.oncanplay=function(){ - this.play(); + Promise.resolve(this.play()).catch(()=>void 0); }; ui.window.appendChild(audio); }, @@ -32038,14 +32695,21 @@ ui.backgroundMusic.src=''; } else if(_status._aozhan==true&&lib.config.mode_config.guozhan.aozhan_bgm!='disabled'){ - var aozhan=lib.config.mode_config.guozhan.aozhan_bgm; + var aozhan=_status.tempAozhan||lib.config.mode_config.guozhan.aozhan_bgm; + if(Array.isArray(aozhan)){ + aozhan=aozhan.randomGet('disabled',_status.currentAozhan)||lib.config.mode_config.guozhan.aozhan_bgm; + } if(aozhan=='random'){ - aozhan=['online','rewrite','chaoming'].randomGet(); + aozhan=Object.keys(lib.mode.guozhan.config.aozhan_bgm.item).randomGet('disabled','random',_status.currentAozhan); } - ui.backgroundMusic.src=lib.assetURL+'audio/background/aozhan_'+aozhan+'.mp3'; + _status.currentAozhan=aozhan; + ui.backgroundMusic.src=lib.assetURL+(aozhan.indexOf('ext:')==0?'extension/'+aozhan.slice(4):'audio/background/aozhan_'+aozhan+'.mp3'); } else{ - var music=lib.config.background_music; + var music=_status.tempMusic||lib.config.background_music; + if(Array.isArray(music)){ + music=music.randomGet('music_off',_status.currentMusic)||lib.config.background_music; + } if(music=='music_random'){ music=lib.config.all.background_music.randomGet('music_off','music_random',_status.currentMusic); } @@ -32056,7 +32720,7 @@ } } else{ - ui.backgroundMusic.src=lib.assetURL+'audio/background/'+music+'.mp3'; + ui.backgroundMusic.src=lib.assetURL+(music.indexOf('ext:')==0?'extension/'+music.slice(4):'audio/background/'+music+'.mp3'); } } }, @@ -34488,106 +35152,67 @@ } }, linexy:function(path){ - var from=[path[0],path[1]]; - var to=[path[2],path[3]]; - var total=typeof arguments[1]==='number'?arguments[1]:lib.config.duration*2; - var opacity=1; - var color=[255,255,255]; - var dashed=false; - var drag=false; - if(typeof arguments[1]=='object'){ - for(var i in arguments[1]){ - switch(i){ - case 'opacity':opacity=arguments[1][i];break; - case 'color':color=arguments[1][i];break; - case 'dashed':dashed=arguments[1][i];break; - case 'duration':total=arguments[1][i];break; - } + const from=[path[0],path[1]],to=[path[2],path[3]]; + let total=typeof arguments[1]==='number'?arguments[1]:lib.config.duration*2,opacity=1,color=[255,255,255],dashed=false,drag=false; + if(typeof arguments[1]=='object') Object.keys(arguments[1]).forEach(value=>{ + switch(value){ + case 'opacity': + opacity=arguments[1][value]; + break; + case 'color': + color=arguments[1][value]; + break; + case 'dashed': + dashed=arguments[1][value]; + break; + case 'duration':total=arguments[1][value]; } - } - else if(arguments[1]=='fire'||arguments[1]=='thunder'||arguments[1]=='green'){ - color=arguments[1]; - } - if(color=='fire'){ - color=[255, 146, 68]; - } - else if(color=='thunder'){ - color=[141, 216, 255]; - } - else if(color=='green'){ - color=[141, 255, 216]; - } - var node; + }); + else if(typeof arguments[1]=='string') color=arguments[1]; + if(typeof color=='string') color=lib.lineColor.get(color)||[255,255,255]; + let node; if(arguments[1]=='drag'){ - color=[236, 201, 71]; + color=[236,201,71]; drag=true; - if(arguments[2]){ - node=arguments[2] - } + if(arguments[2]) node=arguments[2]; else{ node=ui.create.div('.linexy.drag'); - node.style.left=from[0]+'px'; - node.style.top=from[1]+'px'; - node.style.background='linear-gradient(transparent,rgba('+color.toString()+','+opacity+'),rgba('+color.toString()+','+opacity+'))'; - if(game.chess){ - ui.chess.appendChild(node); - } - else{ - ui.arena.appendChild(node); - } + node.style.left=`${from[0]}px`; + node.style.top=`${from[1]}px`; + node.style.background=`linear-gradient(transparent,rgba(${color.toString()},${opacity}),rgba(${color.toString()},${opacity}))`; + if(game.chess) ui.chess.appendChild(node); + else ui.arena.appendChild(node); } } else{ node=ui.create.div('.linexy.hidden'); - node.style.left=from[0]+'px'; - node.style.top=from[1]+'px'; - node.style.background='linear-gradient(transparent,rgba('+color.toString()+','+opacity+'),rgba('+color.toString()+','+opacity+'))'; - node.style.transitionDuration=(total/3000)+'s'; - } - var dy=to[1]-from[1]; - var dx=to[0]-from[0]; - var deg=Math.atan(Math.abs(dy)/Math.abs(dx))/Math.PI*180; - if(dx>=0){ - if(dy<=0){ - deg+=90; - } - else{ - deg=90-deg; - } - } - else{ - if(dy<=0){ - deg=270-deg; - } - else{ - deg+=270; - } - } + node.style.left=`${from[0]}px`; + node.style.top=`${from[1]}px`; + node.style.background=`linear-gradient(transparent,rgba(${color.toString()},${opacity}),rgba(${color.toString()},${opacity}))`; + node.style.transitionDuration=`${total/3000}s`; + } + const dy=to[1]-from[1],dx=to[0]-from[0]; + let deg=Math.atan(Math.abs(dy)/Math.abs(dx))/Math.PI*180; + if(dx>=0) if(dy<=0) deg+=90; + else deg=90-deg; + else if(dy<=0) deg=270-deg; + else deg+=270; if(drag){ - node.style.transform='rotate('+(-deg)+'deg)'; - node.style.height=get.xyDistance(from,to)+'px'; + node.style.transform=`rotate(${(-deg)}deg)`; + node.style.height=`${get.xyDistance(from,to)}px`; } else{ - node.style.transform='rotate('+(-deg)+'deg) scaleY(0)'; - node.style.height=get.xyDistance(from,to)+'px'; - if(get.objtype(arguments[1])=='div'){ - arguments[1].appendChild(node); - } - else if(game.chess){ - ui.chess.appendChild(node); - } - else{ - ui.arena.appendChild(node); - } + node.style.transform=`rotate(${(-deg)}deg) scaleY(0)`; + node.style.height=`${get.xyDistance(from,to)}px`; + if(get.objtype(arguments[1])=='div') arguments[1].appendChild(node); + else if(game.chess) ui.chess.appendChild(node); + else ui.arena.appendChild(node); ui.refresh(node); node.show(); - node.style.transform='rotate('+(-deg)+'deg) scaleY(1)'; - node.listenTransition(function(){ - setTimeout(function(){ - if(node.classList.contains('removing')) return; - node.delete(); - },total/3); - }); + node.style.transform=`rotate(${(-deg)}deg) scaleY(1)`; + node.listenTransition(()=>setTimeout(()=>{ + if(!node.classList.contains('removing')) node.delete(); + },total/3)); } return node; }, @@ -36016,6 +36641,7 @@ if(cards[i].name!=cardname||((cardnature||cards[i].nature)&&cards[i].nature!=cardnature)){ if(!cards[i]._tempName) cards[i]._tempName=ui.create.div('.tempname',cards[i]); var tempname=get.translation(cardname); + cards[i]._tempName.classList[lib.config.cardtempname=='default'?'add':'remove']('vertical'); cards[i]._tempName.dataset.nature='fire'; if(cardname=='sha'){ if(cardnature) tempname=get.translation(cardnature)+tempname; @@ -36823,7 +37449,7 @@ return next; }, chooseCharacterDouble:function(){ - var next=game.createEvent('chooseCharacter',false); + var next=game.createEvent('chooseCharacter'); var config,width,num,ratio,func,update,list,first; for(var i=0;igame.broadcastAll((num1,num2,top)=>{ + if(ui.cardPileNumber) ui.cardPileNumber.innerHTML=`${num1}轮 剩余牌: ${num2}`; + _status.pileTop=top; + },game.roundNumber,ui.cardPile.childNodes.length,ui.cardPile.firstChild), + asyncDraw:(players,num,drawDeck,bottom)=>players.forEach((value,index)=>{ + let num2=1; + if(typeof num=='number') num2=num; + else if(Array.isArray(num)) num2=num[index]; + else if(typeof num=='function') num2=num(value); + if(drawDeck&&drawDeck.drawDeck) value.draw(num2,false,drawDeck); + else if(bottom) value.draw(num2,'nodelay','bottom'); + else value.draw(num2,'nodelay'); + }), asyncDrawAuto:function(players,num,drawDeck){ - if(players.length==1){ - var num2=1; - if(typeof num=='number'){ - num2=num; - } - else if(Array.isArray(num)){ - num2=num[0]; - } - else if(typeof num=='function'){ - num2=num(players[0]); - } - if(drawDeck&&drawDeck.drawDeck){ - players[0].draw(num2,drawDeck); - } - else{ - players[0].draw(num2); - } - } - else{ + if(players.length>1){ game.asyncDraw.apply(this,arguments); + return; } + let num2=1; + if(typeof num=='number') num2=num; + else if(Array.isArray(num)) num2=num[0]; + else if(typeof num=='function') num2=num(players[0]); + if(drawDeck&&drawDeck.drawDeck) players[0].draw(num2,drawDeck); + else players[0].draw(num2); }, - finishSkill:function(i,sub){ - var j; - var mode=get.mode(); - var info=lib.skill[i]; + finishSkill:(i,sub)=>{ + const mode=get.mode(),info=lib.skill[i],iInfo=`${i}_info`; if(info.alter){ - lib.translate[i+'_info_origin']=lib.translate[i+'_info']; - if(!lib.config.vintageSkills.contains(i)){ - lib.translate[i+'_info']=lib.translate[i+'_info_alter']; - } - } - else if(lib.translate[i+'_info_'+mode]){ - lib.translate[i+'_info']=lib.translate[i+'_info_'+mode]; - } - else if(lib.translate[i+'_info_zhu']&&(mode=='identity'||(mode=='guozhan'&&_status.mode=='four'))){ - lib.translate[i+'_info']=lib.translate[i+'_info_zhu']; - } - else if(lib.translate[i+'_info_combat']&&get.is.versus()){ - lib.translate[i+'_info']=lib.translate[i+'_info_combat']; + lib.translate[`${iInfo}_origin`]=lib.translate[iInfo]; + if(!lib.config.vintageSkills.contains(i)) lib.translate[iInfo]=lib.translate[`${iInfo}_alter`]; } + else if(lib.translate[`${iInfo}_${mode}`]) lib.translate[iInfo]=lib.translate[`${iInfo}_${mode}`]; + else if(lib.translate[`${iInfo}_zhu`]&&(mode=='identity'||mode=='guozhan'&&_status.mode=='four')) lib.translate[iInfo]=lib.translate[`${iInfo}_zhu`]; + else if(lib.translate[`${iInfo}_combat`]&&get.is.versus()) lib.translate[iInfo]=lib.translate[`${iInfo}_combat`]; if(info.forbid&&info.forbid.contains(mode)){ lib.skill[i]={}; - if(lib.translate[i+'_info']){ - lib.translate[i+'_info']='此模式下不可用'; - } + if(lib.translate[iInfo]) lib.translate[iInfo]='此模式下不可用'; return; } if(info.mode&&info.mode.contains(mode)==false){ lib.skill[i]={}; - if(lib.translate[i+'_info']){ - lib.translate[i+'_info']='此模式下不可用'; - } + if(lib.translate[iInfo]) lib.translate[iInfo]='此模式下不可用'; return; } if(info.available&&info.available(mode)==false){ lib.skill[i]={}; - if(lib.translate[i+'_info']){ - lib.translate[i+'_info']='此模式下不可用'; - } + if(lib.translate[iInfo]) lib.translate[iInfo]='此模式下不可用'; return; } if(info.viewAs&&typeof info.viewAs!='function'){ - if(typeof info.viewAs=='string'){ - info.viewAs={name:info.viewAs}; - } + if(typeof info.viewAs=='string') info.viewAs={ + name:info.viewAs + }; if(!lib.card[info.viewAs.name]){ lib.skill[i]={}; - lib.translate[i+'_info']='技能不可用'; + lib.translate[iInfo]='技能不可用'; return; } if(info.ai==undefined) info.ai={}; - var skill=info.ai; - var card=lib.card[info.viewAs.name].ai; - for(j in card){ - if(skill[j]==undefined) skill[j]=card[j]; - else if(typeof skill[j]=='object'){ - for(var k in card[j]){ - if(skill[j][k]==undefined) skill[j][k]=card[j][k]; - } - } - } + const skill=info.ai,card=lib.card[info.viewAs.name].ai; + if(card) Object.keys(card).forEach(value=>{ + if(skill[value]==undefined) skill[value]=card[value]; + else if(typeof skill[value]=='object') Object.keys(card[value]).forEach(element=>{ + if(skill[value][element]==undefined) skill[value][element]=card[value][element]; + }); + }); } if(info.inherit){ - var skill=lib.skill[info.inherit]; - for(j in skill){ - if(info[j]==undefined){ - if(j=='audio'&&(typeof info[j]=='number'||typeof info[j]=='boolean')){ - info[j]=info.inherit; - } - else{ - info[j]=skill[j]; - } - } - } - if(lib.translate[i]==undefined){ - lib.translate[i]=lib.translate[info.inherit]; - } - if(lib.translate[i+'_info']==undefined){ - lib.translate[i+'_info']=lib.translate[info.inherit+'_info']; - } + const skill=lib.skill[info.inherit]; + if(skill) Object.keys(skill).forEach(value=>{ + if(info[value]!=undefined) return; + if(value=='audio'&&(typeof info[value]=='number'||typeof info[value]=='boolean')) info[value]=info.inherit; + else info[value]=skill[value]; + }); + if(lib.translate[i]==undefined) lib.translate[i]=lib.translate[info.inherit]; + if(lib.translate[iInfo]==undefined) lib.translate[iInfo]=lib.translate[`${info.inherit}_info`]; } if(info.limited){ if(info.mark===undefined) info.mark=true; if(!info.intro) info.intro={}; if(info.intro.content===undefined) info.intro.content='limited'; if(info.skillAnimation===undefined) info.skillAnimation=true; - if(info.init===undefined) info.init=function(player,skill){ - player.storage[skill]=false; - } - } - if(info.subSkill&&!sub){ - for(var j in info.subSkill){ - lib.skill[i+'_'+j]=info.subSkill[j]; - lib.skill[i+'_'+j].sub=true; - if(info.subSkill[j].name){ - lib.translate[i+'_'+j]=info.subSkill[j].name; - } - else{ - lib.translate[i+'_'+j]=lib.translate[i+'_'+j]||lib.translate[i]; - } - if(info.subSkill[j].description){ - lib.translate[i+'_'+j+'_info']=info.subSkill[j].description; - } - if(info.subSkill[j].marktext){ - lib.translate[i+'_'+j+'_bg']=info.subSkill[j].marktext; - } - game.finishSkill(i+'_'+j,true); - } - } + if(info.init===undefined) info.init=(player,skill)=>player.storage[skill]=false; + } + if(info.subSkill&&!sub) Object.keys(info.subSkill).forEach(value=>{ + const iValue=`${i}_${value}`; + lib.skill[iValue]=info.subSkill[value]; + lib.skill[iValue].sub=true; + if(info.subSkill[value].name) lib.translate[iValue]=info.subSkill[value].name; + else lib.translate[iValue]=lib.translate[iValue]||lib.translate[i]; + if(info.subSkill[value].description) lib.translate[`${iValue}_info`]=info.subSkill[value].description; + if(info.subSkill[value].marktext) lib.translate[`${iValue}_bg`]=info.subSkill[value].marktext; + game.finishSkill(iValue,true); + }); if(info.round){ - var k=i+'_roundcount'; - if(typeof info.group=='string'){ - info.group=[info.group,k]; - } - else if(Array.isArray(info.group)){ - info.group.add(k); - } - else{ - info.group=[k]; - } - lib.skill[k]=(function(round,name){ - return { - init:function(player){ - if(typeof player.storage[name]!=='number') player.storage[name]=1-round; - }, - intro:{ - content:function(storage,player){ - var str=''; - var info=get.info(name.slice(0,name.indexOf('_roundcount'))); - if(info&&info.addintro){ - str+=info.addintro(storage,player); - } - var num=round-(game.roundNumber-storage); - if(num>0){ - str+=get.cnNumber(num)+'轮后'+(info.roundtext||'技能重置'); - } - else{ - str+='技能可发动'; - } - return str; - }, - markcount:function(storage,player){ - var num=round-(game.roundNumber-storage); - if(num>0){ - return num; - } - return 0; - } + const k=`${i}_roundcount`; + if(typeof info.group=='string') info.group=[info.group,k]; + else if(Array.isArray(info.group)) info.group.add(k); + else info.group=[k]; + lib.skill[k]=((round,name)=>({ + init:player=>{ + if(typeof player.storage[name]!=='number') player.storage[name]=1-round; + }, + intro:{ + content:(storage,player)=>{ + let str=''; + const info=get.info(name.slice(0,name.indexOf('_roundcount'))); + if(info&&info.addintro) str+=info.addintro(storage,player); + const num=round-(game.roundNumber-storage); + if(num>0) str+=`${get.cnNumber(num)}轮后${info.roundtext||'技能重置'}`; + else str+='技能可发动'; + return str; }, - trigger:{global:'roundStart'}, - forced:true, - popup:false, - silent:true, - content:function(){ - var skill=event.name.slice(0,event.name.indexOf('_roundcount')); - if(lib.skill[skill].round-(game.roundNumber-player.storage[event.name])>0){ - player.updateMarks(); - } - else{ - player.unmarkSkill(event.name); - } - } - }; - }(info.round,k)); + markcount:(storage,player)=>Math.max(round-(game.roundNumber-storage),0) + }, + trigger:{global:'roundStart'}, + forced:true, + popup:false, + silent:true, + content:()=>{ + if(lib.skill[event.name.slice(0,event.name.indexOf('_roundcount'))].round-(game.roundNumber-player.storage[event.name])>0) player.updateMarks(); + else player.unmarkSkill(event.name); + } + }))(info.round,k); lib.translate[k]=lib.translate[i]||''; - lib.translate[k+'_bg']=lib.translate[i+'_bg']||lib.translate[k][0]; - } - if(info.marktext){ - lib.translate[i+'_bg']=info.marktext; + lib.translate[`${k}_bg`]=lib.translate[`${i}_bg`]||lib.translate[k][0]; } + if(info.marktext) lib.translate[`${i}_bg`]=info.marktext; if(info.silent){ if(!info.hasOwnProperty('forced')) info.forced=true; if(!info.hasOwnProperty('popup')) info.popup=false; } - if(i[0]=='_'){ - game.addGlobalSkill(i); + if(!info.hasOwnProperty('_priority')){ + let priority=0; + if(info.priority){ + priority=info.priority*100; + } + if(info.silent){ + priority++; + } + if(info.equipSkill) priority-=25; + if(info.cardSkill) priority-=50; + if(info.ruleSkill) priority-=75; + info._priority=priority; } + if(i[0]=='_') game.addGlobalSkill(i); }, - finishCards:function(){ + finishCards:()=>{ _status.cardsFinished=true; - var i,j,k; - var mode=get.mode(); - for(i in lib.card){ - if(lib.translate[i+'_info_'+mode]){ - lib.translate[i+'_info']=lib.translate[i+'_info_'+mode]; - } - else if(lib.translate[i+'_info_zhu']&&(mode=='identity'||(mode=='guozhan'&&_status.mode=='four'))){ - lib.translate[i+'_info']=lib.translate[i+'_info_zhu']; - } - else if(lib.translate[i+'_info_combat']&&get.is.versus()){ - lib.translate[i+'_info']=lib.translate[i+'_info_combat']; - } - var card=lib.card[i]; - if(card.filterTarget&&card.selectTarget==undefined){ - card.selectTarget=1; - } + const mode=get.mode(),filterTarget=(card,player,target)=>player==target&&target.canEquip(card,true),aiBasicOrder=(card,player)=>{ + const equipValue=get.equipValue(card,player)/20; + return player&&player.hasSkillTag('reverseEquip')?8.5-equipValue:8+equipValue; + },aiBasicValue=(card,player,index,method)=>{ + if(!player.getCards('e').contains(card)&&!player.canEquip(card,true)) return 0.01; + const info=get.info(card),current=player.getEquip(info.subtype),value=current&&card!=current&&get.value(current,player); + let equipValue=info.ai.equipValue||info.ai.basic.equipValue; + if(typeof equipValue=='function'){ + if(method=='raw')return equipValue(card,player); + if(method=='raw2')return equipValue(card,player)-value; + return Math.max(0.1,equipValue(card,player)-value); + } + if(typeof equipValue!='number') equipValue=0; + if(method=='raw') return equipValue; + if(method=='raw2') return equipValue-value; + return Math.max(0.1,equipValue-value); + },aiResultTarget=(player,target,card)=>get.equipResult(player,target,card.name); + Object.keys(lib.card).forEach(libCardKey=>{ + const info = `${libCardKey}_info`; + if(lib.translate[`${info}_${mode}`]) lib.translate[info]=lib.translate[`${info}_${mode}`]; + else if(lib.translate[`${info}_zhu`]&&(mode=='identity'||mode=='guozhan'&&_status.mode=='four')) lib.translate[info]=lib.translate[`${info}_zhu`]; + else if(lib.translate[`${info}_combat`]&&get.is.versus()) lib.translate[info]=lib.translate[`${info}_combat`]; + const card=lib.card[libCardKey]; + if(card.filterTarget&&card.selectTarget==undefined) card.selectTarget=1; if(card.autoViewAs){ - if(!card.ai){ - card.ai={}; - } + if(!card.ai) card.ai={}; if(!card.ai.order){ card.ai.order=lib.card[card.autoViewAs].ai.order; - if(!card.ai.order&&lib.card[card.autoViewAs].ai.basic){ - card.ai.order=lib.card[card.autoViewAs].ai.basic.order; - } + if(!card.ai.order&&lib.card[card.autoViewAs].ai.basic) card.ai.order=lib.card[card.autoViewAs].ai.basic.order; } } if(card.type=='equip'){ if(card.enable==undefined) card.enable=true; if(card.selectTarget==undefined) card.selectTarget=-1; - if(card.filterTarget==undefined) card.filterTarget=function(card,player,target){ - if(player!=target) return false; - return target.canEquip(card,true); - }; + if(card.filterTarget==undefined) card.filterTarget=filterTarget; if(card.modTarget==undefined) card.modTarget=true; if(card.allowMultiple==undefined) card.allowMultiple=false; if(card.content==undefined) card.content=lib.element.content.equipCard; if(card.toself==undefined) card.toself=true; - if(card.ai==undefined) card.ai={basic:{}}; + if(card.ai==undefined) card.ai={ + basic:{} + }; if(card.ai.basic==undefined) card.ai.basic={}; - if(card.ai.result==undefined) card.ai.result={target:1.5}; - if(card.ai.basic.order==undefined) card.ai.basic.order=function(card,player){ - if(player&&player.hasSkillTag('reverseEquip')){ - return 8.5-get.equipValue(card,player)/20; - } - else{ - return 8+get.equipValue(card,player)/20; - } + if(card.ai.result==undefined) card.ai.result={ + target:1.5 }; + if(card.ai.basic.order==undefined) card.ai.basic.order=aiBasicOrder; if(card.ai.basic.useful==undefined) card.ai.basic.useful=2; if(card.subtype=='equip3'){ if(card.ai.basic.equipValue==undefined) card.ai.basic.equipValue=7; @@ -37626,34 +38170,9 @@ else if(card.subtype=='equip4'){ if(card.ai.basic.equipValue==undefined) card.ai.basic.equipValue=4; } - else{ - if(card.ai.basic.equipValue==undefined) card.ai.basic.equipValue=1; - } - if(card.ai.basic.value==undefined) card.ai.basic.value=function(card,player,index,method){ - if(!player.getCards('e').contains(card)&&!player.canEquip(card,true)) return 0.01; - var value=0; - var info=get.info(card); - var current=player.getEquip(info.subtype); - if(current&&card!=current){ - value=get.value(current,player); - } - var equipValue=info.ai.equipValue; - if(equipValue==undefined){ - equipValue=info.ai.basic.equipValue; - } - if(typeof equipValue=='function'){ - if(method=='raw') return equipValue(card,player); - if(method=='raw2') return equipValue(card,player)-value; - return Math.max(0.1,equipValue(card,player)-value); - } - if(typeof equipValue!='number') equipValue=0; - if(method=='raw') return equipValue; - if(method=='raw2') return equipValue-value; - return Math.max(0.1,equipValue-value); - } - if(!card.ai.result.keepAI) card.ai.result.target=function(player,target,card){ - return get.equipResult(player,target,card.name); - }; + else if(card.ai.basic.equipValue==undefined) card.ai.basic.equipValue=1; + if(card.ai.basic.value==undefined) card.ai.basic.value=aiBasicValue; + if(!card.ai.result.keepAI) card.ai.result.target=aiResultTarget; } else if(card.type=='delay'){ if(card.enable==undefined) card.enable=true; @@ -37661,38 +38180,28 @@ if(card.content==undefined) card.content=lib.element.content.addJudgeCard; if(card.allowMultiple==undefined) card.allowMultiple=false; } - } - for(i in lib.skill){ - game.finishSkill(i); - } + }); + Object.keys(lib.skill).forEach(value=>game.finishSkill(value)); }, checkMod:function(){ - var name=arguments[arguments.length-2]; - var skills=arguments[arguments.length-1]; - if(skills.getSkills){ - //if(name!='cardname') skills=skills.getSkills(); - //else skills=skills.getSkills(null,false); - skills=skills.getSkills(); - } + const argumentArray=Array.from(arguments),name=argumentArray[argumentArray.length-2]; + let skills=argumentArray[argumentArray.length-1]; + if(skills.getSkills) skills=skills.getSkills(); skills=skills.concat(lib.skill.global); game.expandSkills(skills); - skills.sort(function(a,b){ - return get.priority(a)-get.priority(b); + skills=skills.filter(skill=>{ + const info=get.info(skill); + return (info&&info.mod&&info.mod[name]); + }) + skills.sort((a,b)=>get.priority(a)-get.priority(b)); + const arg=argumentArray.slice(0,-2); + skills.forEach(value=>{ + const result=get.info(value).mod[name].apply(this,arg); + if(typeof arg[arg.length-1]!='object'&&result!=undefined) arg[arg.length-1]=result; }); - var arg=[],i,info; - for(i=0;i{ _status.prepareArena=true; game.showHistory(false); ui.create.players(num); @@ -37700,22 +38209,18 @@ ui.create.cardsAsync(); game.finishCards(); }, - clearArena:function(){ + clearArena:()=>{ ui.control.innerHTML=''; ui.arenalog.innerHTML=''; - var nodes=[]; - for(var i=0;i{ + if(value==ui.canvas) return; + if(value==ui.control) return; + if(value==ui.arenalog) return; + if(value==ui.roundmenu) return; + if(value==ui.timer) return; + if(value==ui.autonode) return; + value.remove(); + }); ui.sidebar.innerHTML=''; ui.cardPile.innerHTML=''; ui.discardPile.innerHTML=''; @@ -37726,7 +38231,7 @@ game.dead.length=0; game.me=null; }, - clearConnect:function(){ + clearConnect:()=>{ if(ui.ipnode){ ui.ipnode.remove(); delete ui.ipnode; @@ -37752,137 +38257,108 @@ delete ui.startServer; } if(ui.rooms){ - for(var i=0;ivalue.remove()); delete ui.rooms; } if(ui.roombase){ ui.roombase.remove(); delete ui.roombase; } - if(ui.connectEvents){ - ui.connectEvents.remove(); - ui.connectEventsCount.remove(); - ui.connectClients.remove(); - ui.connectClientsCount.remove(); - ui.createRoomButton.remove(); - delete ui.connectEvents; - delete ui.connectEventsCount; - delete ui.connectClients; - delete ui.connectClientsCount; - delete ui.createRoomButton; - } + if(!ui.connectEvents) return; + ui.connectEvents.remove(); + ui.connectEventsCount.remove(); + ui.connectClients.remove(); + ui.connectClientsCount.remove(); + ui.createRoomButton.remove(); + delete ui.connectEvents; + delete ui.connectEventsCount; + delete ui.connectClients; + delete ui.connectClientsCount; + delete ui.createRoomButton; }, log:function(){ - var str='',str2='',logvid=null; - for(var i=0;i{ + const itemtype=get.itemtype(value); if(itemtype=='player'||itemtype=='players'){ - str+=''+get.translation(arguments[i])+''; - str2+=get.translation(arguments[i]); + str+=`${get.translation(value)}`; + str2+=get.translation(value); } - else if(itemtype=='cards'||itemtype=='card'||(typeof arguments[i]=='object'&&arguments[i]&&arguments[i].name)){ - str+=''+get.translation(arguments[i])+''; - str2+=get.translation(arguments[i]); + else if(itemtype=='cards'||itemtype=='card'||(typeof value=='object'&&value&&value.name)){ + str+=`${get.translation(value)}`; + str2+=get.translation(value); } - else if(typeof arguments[i]=='object'){ - if(arguments[i]){ - if(arguments[i].parentNode==ui.historybar){ - logvid=arguments[i].logvid; - } - else{ - str+=get.translation(arguments[i]); - str2+=get.translation(arguments[i]); - } + else if(typeof value=='object'){ + if(value.parentNode==ui.historybar) logvid=value.logvid; + else{ + str+=get.translation(value); + str2+=get.translation(value); } } - else if(typeof arguments[i]=='string'){ - if(arguments[i][0]=='【'&&arguments[i][arguments[i].length-1]=='】'){ - str+=''+get.translation(arguments[i])+''; - str2+=get.translation(arguments[i]); + else if(typeof value=='string'){ + if(value[0]=='【'&&value[value.length-1]=='】'){ + str+=`${get.translation(value)}`; + str2+=get.translation(value); } - else if(arguments[i][0]=='#'){ - var color=''; - switch(arguments[i][1]){ - case 'b':color='blue';break; - case 'y':color='yellow';break; - case 'g':color='green';break; - } - str+=''+get.translation(arguments[i].slice(2))+''; - str2+=get.translation(arguments[i].slice(2)); + else if(value[0]=='#'){ + str+=`${get.translation(value.slice(2))}`; + str2+=get.translation(value.slice(2)); } else{ - str+=get.translation(arguments[i]); - str2+=get.translation(arguments[i]); + str+=get.translation(value); + str2+=get.translation(value); } } else{ - str+=arguments[i]; - str2+=arguments[i]; + str+=value; + str2+=value; } - - } - var node=ui.create.div(); + }); + const node=ui.create.div(); node.innerHTML=lib.config.log_highlight?str:str2; ui.sidebar.insertBefore(node,ui.sidebar.firstChild); game.addVideo('log',null,lib.config.log_highlight?str:str2); - game.broadcast(function(str,str2){ - game.log(lib.config.log_highlight?str:str2); - },str,str2); + game.broadcast((str,str2)=>game.log(lib.config.log_highlight?str:str2),str,str2); if(!_status.video&&!game.online){ - if(!logvid){ - logvid=_status.event.getLogv(); - } - if(logvid){ - game.logv(logvid,'
    '+lib.config.log_highlight?str:str2+'
    '); - } - } - // if(lib.config.title) document.title=lib.config.log_highlight?str:str2; - if(lib.config.show_log!='off'&&!game.chess){ - var nodeentry=node.cloneNode(true); - ui.arenalog.insertBefore(nodeentry,ui.arenalog.firstChild); - if(!lib.config.clear_log){ - while(ui.arenalog.childNodes.length&&ui.arenalog.scrollHeight>ui.arenalog.offsetHeight){ - ui.arenalog.lastChild.remove(); - } - } - if(!lib.config.low_performance){ - nodeentry.style.transition='all 0s'; - nodeentry.style.marginBottom=(-nodeentry.offsetHeight)+'px'; - ui.refresh(nodeentry); - nodeentry.style.transition=''; - nodeentry.style.marginBottom=''; - } - if(lib.config.clear_log){ - nodeentry.timeout=setTimeout(function(){ - nodeentry.delete(); - },1000); - for(var i=0;i${lib.config.log_highlight?str:str2}`); + else logvid=_status.event.getLogv(); + } + if(lib.config.show_log=='off'||game.chess) return; + const nodeentry=node.cloneNode(true); + ui.arenalog.insertBefore(nodeentry,ui.arenalog.firstChild); + if(!lib.config.clear_log) while(ui.arenalog.childNodes.length&&ui.arenalog.scrollHeight>ui.arenalog.offsetHeight){ + ui.arenalog.lastChild.remove(); + } + if(!lib.config.low_performance){ + nodeentry.style.transition='all 0s'; + nodeentry.style.marginBottom=`-${nodeentry.offsetHeight}px`; + ui.refresh(nodeentry); + nodeentry.style.transition=''; + nodeentry.style.marginBottom=''; + } + if(!lib.config.clear_log) return; + nodeentry.timeout=setTimeout(()=>nodeentry.delete(),1000); + Array.from(ui.arenalog.childNodes).forEach(value=>{ + if(!value.timeout) value.remove(); + }); }, - logv:function(player,card,targets,event,forced,logvid){ - var node=ui.create.div('.hidden'); - node.node={}; - logvid=logvid||get.id(); + logv:(player,card,targets,event,forced,logvid)=>{ if(!player){ player=_status.event.getParent().logvid; if(!player) return; } - game.broadcast(function(player,card,targets,event,forced,logvid){ - game.logv(player,card,targets,event,forced,logvid); - },player,card,targets,event,forced,logvid); + const node=ui.create.div('.hidden'); + node.node={}; + logvid=logvid||get.id(); + game.broadcast(game.logv,player,card,targets,event,forced,logvid); if(typeof player=='string'){ - for(var i=0;ivalue.logvid==player); + if(childNode) childNode.added.push(card); return; } if(typeof card=='string'){ @@ -37890,23 +38366,17 @@ if(lib.skill[card]&&lib.skill[card].logv===false&&!forced) return; if(!lib.translate[card]) return; } - var avatar; - if(!player.isUnseen(0)){ - avatar=player.node.avatar.cloneNode(); - } - else if(!player.isUnseen(1)){ - avatar=player.node.avatar2.cloneNode(); - } - else{ - return; - } + let avatar; + if(!player.isUnseen(0)) avatar=player.node.avatar.cloneNode(); + else if(!player.isUnseen(1)) avatar=player.node.avatar2.cloneNode(); + else return; node.node.avatar=avatar; avatar.style.transform=''; avatar.className='avatar'; if(card=='die'){ node.dead=true; node.player=player; - var avatar2=avatar.cloneNode(); + const avatar2=avatar.cloneNode(); avatar2.className='avatarbg grayscale1'; avatar.appendChild(avatar2); avatar.style.opacity=0.6; @@ -37919,21 +38389,14 @@ node.appendChild(avatar); if(card=='die'&&targets&&targets!=player){ node.source=targets; - var avatar; player=targets; - if(!player.isUnseen(0)){ - avatar=player.node.avatar.cloneNode(); - } - else if(!player.isUnseen(1)){ - avatar=player.node.avatar2.cloneNode(); - } + if(!player.isUnseen(0)) avatar=player.node.avatar.cloneNode(); + else if(!player.isUnseen(1)) avatar=player.node.avatar2.cloneNode(); else if(get.mode()=='guozhan'&&player.node&&player.node.name_seat){ avatar=ui.create.div('.avatar.cardbg'); avatar.innerHTML=player.node.name_seat.innerHTML[0]; } - else{ - return; - } + else return; avatar.style.transform=''; node.node.avatar2=avatar; avatar.classList.add('avatar2'); @@ -37941,73 +38404,52 @@ } } else if(Array.isArray(card)){ - node.cards=card[1]; + node.cards=card[1].slice(0) card=card[0]; - var info=[card.suit||'',card.number||'',card.name||'',card.nature||'']; - if(!Array.isArray(node.cards)||!node.cards.length){ - node.cards=[ui.create.card(node,'noclick',true).init(info)]; - } + const info=[card.suit||'',card.number||'',card.name||'',card.nature||'']; + if(!Array.isArray(node.cards)||!node.cards.length) node.cards=[ui.create.card(node,'noclick',true).init(info)]; if(card.name=='wuxie'){ if(ui.historybar.firstChild&&ui.historybar.firstChild.type=='wuxie'){ ui.historybar.firstChild.players.push(player); ui.historybar.firstChild.cards.addArray(node.cards); return; } - else{ - node.type='wuxie'; - node.players=[player]; - } - } - if(card.copy){ - card.copy(node,false); + node.type='wuxie'; + node.players=[player]; } + if(card.copy) card.copy(node,false); else{ card=ui.create.card(node,'noclick',true); card.init(info); } - var avatar; - if(!player.isUnseen(0)){ - avatar=player.node.avatar.cloneNode(); - } - else if(!player.isUnseen(1)){ - avatar=player.node.avatar2.cloneNode(); - } + let avatar; + if(!player.isUnseen(0)) avatar=player.node.avatar.cloneNode(); + else if(!player.isUnseen(1)) avatar=player.node.avatar2.cloneNode(); else if(get.mode()=='guozhan'&&player.node&&player.node.name_seat){ avatar=ui.create.div('.avatar.cardbg'); avatar.innerHTML=player.node.name_seat.innerHTML[0]; } - else{ - return; - } + else return; node.node.avatar=avatar; avatar.style.transform=''; avatar.classList.add('avatar2'); node.appendChild(avatar); - - if(targets&&targets.length==1&&targets[0]!=player&&get.itemtype(targets[0])=='player'){ - (function(){ - var avatar2; - var target=targets[0]; - if(!target.isUnseen(0)){ - avatar2=target.node.avatar.cloneNode(); - } - else if(!player.isUnseen(1)){ - avatar2=target.node.avatar2.cloneNode(); - } - else if(get.mode()=='guozhan'&&target.node&&target.node.name_seat){ - avatar2=ui.create.div('.avatar.cardbg'); - avatar2.innerHTML=target.node.name_seat.innerHTML[0]; - } - else{ - return; - } - node.node.avatar2=avatar2; - avatar2.style.transform=''; - avatar2.classList.add('avatar2'); - avatar2.classList.add('avatar3'); - node.insertBefore(avatar2,avatar); - }()); - } + if(targets&&targets.length==1&&targets[0]!=player&&get.itemtype(targets[0])=='player') (()=>{ + let avatar2; + const target=targets[0]; + if(!target.isUnseen(0)) avatar2=target.node.avatar.cloneNode(); + else if(!player.isUnseen(1)) avatar2=target.node.avatar2.cloneNode(); + else if(get.mode()=='guozhan'&&target.node&&target.node.name_seat){ + avatar2=ui.create.div('.avatar.cardbg'); + avatar2.innerHTML=target.node.name_seat.innerHTML[0]; + } + else return; + node.node.avatar2=avatar2; + avatar2.style.transform=''; + avatar2.classList.add('avatar2'); + avatar2.classList.add('avatar3'); + node.insertBefore(avatar2,avatar); + })(); } if(targets&&targets.length){ if(targets.length==1&&targets[0]==player){ @@ -38017,35 +38459,23 @@ node.targets=targets; } } - var fullheight=ui.historybar.offsetHeight; - var num=Math.round((fullheight-8)/50); - var margin=(fullheight-42*num)/(num+1); + const fullheight=ui.historybar.offsetHeight,num=Math.round((fullheight-8)/50),margin=(fullheight-42*num)/(num+1); node.style.transform='scale(0.8)'; ui.historybar.insertBefore(node,ui.historybar.firstChild); ui.refresh(node); node.classList.remove('hidden'); - for(var i=0;i{ + if(index()=>current.remove())(value),500); + }); + if(lib.config.touchscreen) node.addEventListener('touchstart',ui.click.intro); else{ - // node.addEventListener('mouseenter',ui.click.intro); node.addEventListener(lib.config.pop_logv?'mousemove':'click',ui.click.logv); node.addEventListener('mouseleave',ui.click.logvleave); } @@ -38064,8 +38494,7 @@ return; } lib.status.reload++; - var put=lib.db.transaction([type],'readwrite').objectStore(type).put(item,id); - put.onsuccess=function(){ + lib.db.transaction([type],'readwrite').objectStore(type).put(item,id).onsuccess=function(){ if(callback){ _status.dburgent=true; callback.apply(this,arguments); @@ -38085,30 +38514,28 @@ return; } lib.status.reload++; - var store=lib.db.transaction([type],'readwrite').objectStore(type); + const store=lib.db.transaction([type],'readwrite').objectStore(type); if(id){ - store.get(id).onsuccess=function(e){ + store.get(id).onsuccess=e=>{ _status.dburgent=true; callback(e.target.result); delete _status.dburgent; game.reload2(); }; + return; } - else{ - var obj={}; - store.openCursor().onsuccess=function(e){ - var cursor=e.target.result; - if(cursor){ - obj[cursor.key]=cursor.value; - cursor.continue(); - } - else{ - _status.dburgent=true; - callback(obj); - delete _status.dburgent; - game.reload2(); - } + const obj={}; + store.openCursor().onsuccess=e=>{ + const cursor=e.target.result; + if(cursor){ + obj[cursor.key]=cursor.value; + cursor.continue(); + return; } + _status.dburgent=true; + callback(obj); + delete _status.dburgent; + game.reload2(); } }, deleteDB:function(type,id,callback){ @@ -38120,332 +38547,234 @@ lib[_status.dburgent?'ondb2':'ondb'].push(['deleteDB',Array.from(arguments)]); return; } - if(arguments.length==1){ - game.getDB(type,null,function(obj){ - var store=lib.db.transaction([type],'readwrite').objectStore(type); - for(var id in obj){ - lib.status.reload++; - } - for(var id in obj){ - store.delete(id).onsuccess=game.reload2; - } - game.reload2(); - }); - } - else{ + const store=lib.db.transaction([type],'readwrite').objectStore(type); + if(arguments.length!=1){ lib.status.reload++; - var store=lib.db.transaction([type],'readwrite').objectStore(type); store.delete(id).onsuccess=function(){ - if(callback){ - callback.apply(this,arguments); - } + if(callback) callback.apply(this,arguments); game.reload2(); }; + return; } + game.getDB(type,null,obj=>{ + const objKeys=Object.keys(obj); + lib.status.reload+=objKeys.length; + objKeys.forEach(value=>store.delete(value).onsuccess=game.reload2); + game.reload2(); + }); }, - save:function(key,value,mode){ + save:(key,value,mode)=>{ if(_status.reloading) return; mode=mode||lib.config.mode; - if(!lib.db){ - var config={}; - if(key){ - try{ - config=JSON.parse(localStorage.getItem(lib.configprefix+mode)); - if(typeof config!='object') throw 'err'; - } - catch(err){ - config={}; - } - if(value==undefined){ - delete config[key]; - if(mode==lib.config.mode) delete lib.storage[key]; - } - else{ - config[key]=value; - if(mode==lib.config.mode) lib.storage[key]=value; - } - config.version=lib.version; - localStorage.setItem(lib.configprefix+mode,JSON.stringify(config)); + if(lib.db){ + if(!key){ + game.putDB('data',mode,get.copy(lib.storage)); + return; } - else{ - localStorage.setItem(lib.configprefix+mode,JSON.stringify(lib.storage)); + if(mode==lib.config.mode){ + if(value==undefined) delete lib.storage[key]; + else lib.storage[key]=value; + lib.storage.version=lib.version; + game.putDB('data',mode,lib.storage); } + else game.getDB('data',mode,config=>{ + if(!config) config={}; + if(value==undefined) delete config[key]; + else config[key]=value; + config.version=lib.version; + game.putDB('data',mode,config); + }); + return; + } + if(!key){ + localStorage.setItem(`${lib.configprefix}${mode}`,JSON.stringify(lib.storage)); + return; + } + let config; + try{ + config=JSON.parse(localStorage.getItem(`${lib.configprefix}${mode}`)); + if(typeof config!='object') throw 'err'; + } + catch(err){ + config={}; + } + if(value==undefined){ + delete config[key]; + if(mode==lib.config.mode) delete lib.storage[key]; } else{ - if(key){ - if(mode==lib.config.mode){ - if(value==undefined){ - delete lib.storage[key]; - } - else{ - lib.storage[key]=value; - } - lib.storage.version=lib.version; - game.putDB('data',mode,lib.storage); - } - else{ - game.getDB('data',mode,function(config){ - if(!config) config={}; - if(value==undefined){ - delete config[key]; - } - else{ - config[key]=value; - } - config.version=lib.version; - game.putDB('data',mode,config); - }); - } + config[key]=value; + if(mode==lib.config.mode) lib.storage[key]=value; + } + config.version=lib.version; + localStorage.setItem(`${lib.configprefix}${mode}`,JSON.stringify(config)); + }, + showChangeLog:()=>{ + if(lib.version==lib.config.version&&!_status.extensionChangeLog) return; + const ul=document.createElement('ul'); + ul.style.textAlign='left'; + const caption=lib.version==lib.config.version?'扩展更新':`${lib.version}更新内容`; + let players=null,cards=null; + if(lib.version!=lib.config.version) lib.changeLog.forEach(value=>{ + if(value.indexOf('players://')==0) try{ + players=JSON.parse(value.slice(10)).filter(value=>lib.character[value]); } - else{ - game.putDB('data',mode,get.copy(lib.storage)); + catch(e){ + players=null; } - } - }, - showChangeLog:function(){ - if(lib.version!=lib.config.version||_status.extensionChangeLog){ - var ul=document.createElement('ul'); - ul.style.textAlign='left'; - var caption; - var players=null,cards=null; - if(lib.version!=lib.config.version){ - for(var i=0;ilib.card[value]); } - else{ - caption='扩展更新'; + catch(e){ + cards=null; } - game.saveConfig('version',lib.version); - for(var i in _status.extensionChangeLog){ - var li=document.createElement('li'); - li.innerHTML=i+':'+_status.extensionChangeLog[i]; + else{ + const li=document.createElement('li'); + li.innerHTML=value; ul.appendChild(li); } - var dialog=ui.create.dialog(caption,'hidden'); - var lic=ui.create.div(dialog.content); - lic.style.display='block'; - ul.style.display='inline-block'; - ul.style.marginLeft='-40px'; - lic.appendChild(ul); - if(players){ - for(var i=0;i