diff --git a/README.md b/README.md index a6a416cab..3a5b36c02 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +noname-server.exe的源码见以下仓库: + +https://github.com/nonameShijian/noname-server + +--- + 在线试玩: https://spmario233.github.io/noname/index.html (图片素材加载速度较慢,不推荐) diff --git a/audio/die/liyi.mp3 b/audio/die/liyi.mp3 new file mode 100644 index 000000000..28b47f00a Binary files /dev/null and b/audio/die/liyi.mp3 differ diff --git a/audio/die/muludawang.mp3 b/audio/die/muludawang.mp3 new file mode 100644 index 000000000..6ba900b5e Binary files /dev/null and b/audio/die/muludawang.mp3 differ diff --git a/audio/die/ol_dingshangwan.mp3 b/audio/die/ol_dingshangwan.mp3 new file mode 100644 index 000000000..70b978c9a Binary files /dev/null and b/audio/die/ol_dingshangwan.mp3 differ diff --git a/audio/die/sb_caopi.mp3 b/audio/die/sb_caopi.mp3 new file mode 100644 index 000000000..81c874a5f Binary files /dev/null and b/audio/die/sb_caopi.mp3 differ diff --git a/audio/skill/olchanshuang1.mp3 b/audio/skill/olchanshuang1.mp3 new file mode 100644 index 000000000..052ef3927 Binary files /dev/null and b/audio/skill/olchanshuang1.mp3 differ diff --git a/audio/skill/olchanshuang2.mp3 b/audio/skill/olchanshuang2.mp3 new file mode 100644 index 000000000..cb695a8d3 Binary files /dev/null and b/audio/skill/olchanshuang2.mp3 differ diff --git a/audio/skill/olfengyan1.mp3 b/audio/skill/olfengyan1.mp3 new file mode 100644 index 000000000..384ba3963 Binary files /dev/null and b/audio/skill/olfengyan1.mp3 differ diff --git a/audio/skill/olfengyan2.mp3 b/audio/skill/olfengyan2.mp3 new file mode 100644 index 000000000..3016eebdd Binary files /dev/null and b/audio/skill/olfengyan2.mp3 differ diff --git a/audio/skill/olfudao1.mp3 b/audio/skill/olfudao1.mp3 new file mode 100644 index 000000000..46952ff79 Binary files /dev/null and b/audio/skill/olfudao1.mp3 differ diff --git a/audio/skill/olfudao2.mp3 b/audio/skill/olfudao2.mp3 new file mode 100644 index 000000000..2b7e11c45 Binary files /dev/null and b/audio/skill/olfudao2.mp3 differ diff --git a/audio/skill/olzhanjin1.mp3 b/audio/skill/olzhanjin1.mp3 new file mode 100644 index 000000000..d9b40d5e6 Binary files /dev/null and b/audio/skill/olzhanjin1.mp3 differ diff --git a/audio/skill/olzhanjin2.mp3 b/audio/skill/olzhanjin2.mp3 new file mode 100644 index 000000000..cd4dd64a6 Binary files /dev/null and b/audio/skill/olzhanjin2.mp3 differ diff --git a/audio/skill/sbfangzhu1.mp3 b/audio/skill/sbfangzhu1.mp3 new file mode 100644 index 000000000..eb97bd9d7 Binary files /dev/null and b/audio/skill/sbfangzhu1.mp3 differ diff --git a/audio/skill/sbfangzhu2.mp3 b/audio/skill/sbfangzhu2.mp3 new file mode 100644 index 000000000..a9f474247 Binary files /dev/null and b/audio/skill/sbfangzhu2.mp3 differ diff --git a/audio/skill/sbsongwei1.mp3 b/audio/skill/sbsongwei1.mp3 new file mode 100644 index 000000000..42004bf0e Binary files /dev/null and b/audio/skill/sbsongwei1.mp3 differ diff --git a/audio/skill/sbsongwei2.mp3 b/audio/skill/sbsongwei2.mp3 new file mode 100644 index 000000000..2b6ea4d6b Binary files /dev/null and b/audio/skill/sbsongwei2.mp3 differ diff --git a/audio/skill/sbxingshang1.mp3 b/audio/skill/sbxingshang1.mp3 new file mode 100644 index 000000000..03b995f33 Binary files /dev/null and b/audio/skill/sbxingshang1.mp3 differ diff --git a/audio/skill/sbxingshang2.mp3 b/audio/skill/sbxingshang2.mp3 new file mode 100644 index 000000000..c5b64a083 Binary files /dev/null and b/audio/skill/sbxingshang2.mp3 differ diff --git a/audio/skill/shoufa1.mp3 b/audio/skill/shoufa1.mp3 new file mode 100644 index 000000000..72930e704 Binary files /dev/null and b/audio/skill/shoufa1.mp3 differ diff --git a/audio/skill/shoufa2.mp3 b/audio/skill/shoufa2.mp3 new file mode 100644 index 000000000..954313999 Binary files /dev/null and b/audio/skill/shoufa2.mp3 differ diff --git a/audio/skill/yuxiang.mp3 b/audio/skill/yuxiang.mp3 new file mode 100644 index 000000000..9f3ebd578 Binary files /dev/null and b/audio/skill/yuxiang.mp3 differ diff --git a/audio/skill/zhoulin1.mp3 b/audio/skill/zhoulin1.mp3 new file mode 100644 index 000000000..6e903fbb6 Binary files /dev/null and b/audio/skill/zhoulin1.mp3 differ diff --git a/audio/skill/zhoulin2.mp3 b/audio/skill/zhoulin2.mp3 new file mode 100644 index 000000000..1928ec8ba Binary files /dev/null and b/audio/skill/zhoulin2.mp3 differ diff --git a/card/guozhan.js b/card/guozhan.js index a20186b82..12c4a36de 100644 --- a/card/guozhan.js +++ b/card/guozhan.js @@ -671,9 +671,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ list.push('摸'+(num-i)+'回'+i); } target.chooseControl(list).set('prompt','请分配自己的摸牌数和回复量').ai=function(){ - if(player.hasSkill('diaohulishan')) return 0; - if(_status._aozhan) return list.length-1; - return list.randomGet(); + return Math.min(_status.event.player.getDamagedHp(),list.length)-1; }; } } diff --git a/card/standard.js b/card/standard.js index e979cc202..b8bc21f08 100644 --- a/card/standard.js +++ b/card/standard.js @@ -2679,6 +2679,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ priority:5, popup:false, forced:true, + silent:true, filter:function(event,player){ if(event.card.storage&&event.card.storage.nowuxie) return false; var card=event.card; diff --git a/card/yongjian.js b/card/yongjian.js index 5e0a3e7e1..e8bbf0af6 100644 --- a/card/yongjian.js +++ b/card/yongjian.js @@ -414,7 +414,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ filter:(event,player)=>event.player!=player, logTarget:'player', content:()=>{ - trigger.deniedGift.add(trigger.card); + trigger.deniedGifts.add(trigger.card); }, ai:{ refuseGifts:true diff --git a/character/clan.js b/character/clan.js index 4808a8488..0b229f327 100644 --- a/character/clan.js +++ b/character/clan.js @@ -1927,7 +1927,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ list.sort((a,b)=>{ var del1=lib.inpile.indexOf(a[2])-lib.inpile.indexOf(b[2]); if(del1!=0) return del1; - var a1=0,a2=0; + var a1=0,b1=0; if(a.length>3) a1=(lib.nature.get(a)||0); if(b.length>3) b1=(lib.nature.get(b)||0); return a1-b1; diff --git a/character/collab.js b/character/collab.js index efa39ab4f..5475eb79e 100644 --- a/character/collab.js +++ b/character/collab.js @@ -387,6 +387,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ //会玩孙权 dczhiheng:{ audio:'rezhiheng', + init:(player)=>{ + player.storage.dczhiheng_hit=[]; + }, enable:'phaseUse', position:'he', filterCard:lib.filter.cardDiscardable, @@ -440,12 +443,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, hit:{ charlotte:true, - onremove:true, + onremove:(player)=>{ + player.storage.dczhiheng_hit=[]; + }, mark:true, marktext:'衡', intro:{ - markcount:function(storage,player){ - return player.getStorage('dczhiheng_hit').length; + markcount:function(storage){ + if(storage) return storage.length; + return 0; }, content:'本回合已对$造成过伤害', }, diff --git a/character/extra.js b/character/extra.js index 2b712a371..85b9e5782 100755 --- a/character/extra.js +++ b/character/extra.js @@ -232,7 +232,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ case '鹤': return true; case '猿': - return game.hasPlayer(target=>target!=playertarget.countGainableCards(player,'e')); + return game.hasPlayer(target=>target!=player&&target.countGainableCards(player,'e')); default: return false; } @@ -6061,7 +6061,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ onremove:function(player){ game.countPlayer2(current=>{ if(current.getStorage('dawu2').includes(player)){ - current.unmarkAuto('dawu2',player); + current.unmarkAuto('dawu2',[player]); current.removeAdditionalSkill(`dawu_${player.playerid}`); } },true); diff --git a/character/huicui.js b/character/huicui.js index ee7421fa8..98f9f8b4c 100644 --- a/character/huicui.js +++ b/character/huicui.js @@ -1684,9 +1684,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcminze:{ audio:2, enable:'phaseUse', - filter:function(event,player){ - return !player.hasSkill('dcminze_ban'); - }, filterTarget:function(card,player,target){ if(player.getStorage('dcminze_targeted').includes(target)) return false; return target.countCards('h')get.name(i,player))); - 'step 1' - if(target.countCards('h')>player.countCards('h')){ - player.addTempSkill('dcminze_ban','phaseUseAfter'); - } }, ai:{ order:6.5, @@ -1720,7 +1712,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, subSkill:{ targeted:{onremove:true,charlotte:true}, - ban:{charlotte:true}, given:{ charlotte:true, onremove:true, @@ -5395,7 +5386,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var dialog=ui.create.dialog('劝谏:令一名其他角色…','hidden'); dialog.add([[ ['damage','对其攻击范围内的一名角色造成1点伤害'], - ['draw','将其手牌数调整至体力上限(至多摸至五张),且其本回合内不能使用手牌'] + ['draw','将其手牌数调整至手牌上限(至多摸至五张),且其本回合内不能使用手牌'] ],'textbutton']); return dialog; }, @@ -5408,7 +5399,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, prompt:function(links){ if(links[0]=='damage') return '令一名其他角色对攻击范围内的另一名角色造成1点伤害'; - return '令一名其他角色将手牌数调整至体力上限(至多摸至五张)且本回合内不能使用手牌'; + return '令一名其他角色将手牌数调整至手牌上限(至多摸至五张)且本回合内不能使用手牌'; }, }, ai:{ @@ -5466,15 +5457,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){ filterTarget:function(card,player,target){ if(target==player) return false; var num=target.countCards('h'); - if(num>target.maxHp) return true; - return numtarget.getHandcardLimit()) return true; + return numfalse, selectCard:-1, content:function(){ 'step 0' player.addTempSkill('dcquanjian_draw','phaseUseAfter'); - var num1=target.countCards('h'),num2=target.maxHp; + var num1=target.countCards('h'),num2=target.getHandcardLimit(); var num=0; if(num1>num2){ event.index=0; @@ -5518,7 +5509,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ai:{ result:{ target:function(player,target){ - var num1=target.countCards('h'),num2=target.maxHp; + var num1=target.countCards('h'),num2=target.getHandcardLimit(); if(num1>num2) return -1; return Math.min(5,num2)-num1; }, @@ -10520,7 +10511,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ content:function(){ player.markAuto('dcxunji_effect',[target]); player.addTempSkill('dcxunji_effect',{player:'die'}); - target.markSkill('dcxunji_mark'); + target.addTempSkill('dcxunji_mark',{player:'phaseEnd'}); }, ai:{ order:1, @@ -10533,6 +10524,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, subSkill:{ mark:{ + mark:true, marktext:'嫉', intro:{content:'你已经被盯上了!'}, }, @@ -10564,10 +10556,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ forced:true, popup:false, filter:function(event,player){ - return event.card&&event.card.name=='juedou'&&event.getParent().skill=='dcxunji_effect'; + return event.card&&event.card.name=='juedou'&&event.getParent().skill=='dcxunji_effect'&&event.player.isIn(); }, content:function(){ - player.loseHp(trigger.num); + trigger.player.line(player); + player.damage(trigger.num,trigger.player); }, }, }, @@ -11178,7 +11171,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ zhuangdan_info:'锁定技,其他角色的回合结束时,若你的手牌数为全场唯一最多,则你令〖裂胆〗失效直到你下回合结束。', dc_caiyang:'蔡阳', dcxunji:'寻嫉', - dcxunji_info:'出牌阶段限一次,你可以选择一名其他角色。该角色的下个结束阶段开始时,若其于该回合内造成过伤害,则你视为对其使用一张【决斗】,且当此【决斗】对其造成伤害后,你失去等量的体力。', + dcxunji_info:'出牌阶段限一次,你可以选择一名其他角色。该角色的下个结束阶段开始时,若其于该回合内造成过伤害,则你视为对其使用一张【决斗】,且当此【决斗】对其造成伤害后,其对你造成等量的伤害。', dcjiaofeng:'交锋', dcjiaofeng_info:'锁定技。每回合限一次,当你造成伤害时,若你本回合内未造成过其他伤害且你已损失的体力值:大于0,则你摸一张牌;大于1,则此伤害+1;大于2,则你回复1点体力。', zhoushan:'周善', @@ -11388,7 +11381,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcyongbi_info:'限定技。出牌阶段,你可以将所有手牌交给一名其他男性角色。你将〖媵予〗的发动时机改为“准备阶段和结束阶段开始时”。然后若这些牌中包含的花色数:大于1,则你与其本局游戏的手牌上限+2;大于2,则当你或其于本局游戏内受到大于1的伤害时,此伤害-1。', dc_huangquan:'黄权', dcquanjian:'劝谏', - dcquanjian_info:'出牌阶段每项各限一次。你可以选择一项流程并选择一名其他角色A:⒈令A对其攻击范围内的另一名角色B造成1点伤害。⒉令A将手牌数调整至体力上限(至多摸至五张),且其本回合内不能使用或打出手牌。然后A选择一项:⒈执行此流程。⒉本回合下次受到的伤害+1。', + dcquanjian_info:'出牌阶段每项各限一次。你可以选择一项流程并选择一名其他角色A:⒈令A对其攻击范围内的另一名角色B造成1点伤害。⒉令A将手牌数调整至手牌上限(至多摸至五张),且其本回合内不能使用或打出手牌。然后A选择一项:⒈执行此流程。⒉本回合下次受到的伤害+1。', dctujue:'途绝', dctujue_info:'限定技。当你进入濒死状态时,你可以将所有牌交给一名其他角色。然后你回复等量的体力并摸等量的牌。', chengui:'陈珪', @@ -11545,7 +11538,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dczuowei_info:'当你于回合内使用牌时,你可以根据你的手牌数执行对应效果:大于X,令此牌不可被响应;等于X,对一名其他角色造成1点伤害;小于X,摸两张牌且不能于本回合再触发该选项(X为你装备区里牌的数量且至少为1)。', liuchongluojun:'刘宠骆俊', dcminze:'悯泽', - dcminze_info:'①出牌阶段每名角色限一次。你可以将至多两张牌名不同的牌交给一名手牌数小于你的角色,若其因此手牌数大于你,〖悯泽①〗于此阶段失效。②结束阶段,你将手牌摸至X张(X为你本回合因〖悯泽①〗失去过的牌的牌名数且至多为5)。', + dcminze_info:'①出牌阶段每名角色限一次。你可以将至多两张牌名不同的牌交给一名手牌数小于你的角色。②结束阶段,你将手牌摸至X张(X为你本回合因〖悯泽①〗失去过的牌的牌名数且至多为5)。', dcjini:'击逆', dcjini_info:'当你受到伤害后,你可以重铸至多Y张手牌(Y为你的体力上限减本回合你以此法重铸过的牌数)。若你以此法获得了【杀】,你可以对伤害来源使用一张无视距离且不可被响应的【杀】。', yuechen:'乐綝', diff --git a/character/jsrg.js b/character/jsrg.js index dcec247c7..1a1ec1eea 100644 --- a/character/jsrg.js +++ b/character/jsrg.js @@ -767,7 +767,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(roundCount<=0) break; } if(!player.storage.jsrgzhendan_mark&&count>0) return true; - return false; + return false; }, forced:true, locked:false, @@ -993,6 +993,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return '手牌上限+'+storage; } }, + onremove:true, charlotte:true, mod:{ maxHandcard(player,num){ @@ -8296,7 +8297,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ jsrgpianchong_info:'一名角色的结束阶段,若你于此回合内失去过牌,你可以判定。若结果为红色/黑色,你摸此回合进入弃牌堆的红色/黑色牌数量的牌。', jsrgzunwei:'尊位', jsrgzunwei_info:'出牌阶段限一次。你可以选择一名其他角色并选择执行一项,然后移除该选项:1.将手牌数摸至与该角色相同(最多摸五张);2.将其装备牌移至你的装备区,直到你装备区的牌数不少于其;3.将体力值回复至与该角色相同。', - + xumou_jsrg:'蓄谋', xumou_jsrg_info:'“蓄谋”牌可在判定区内重复存在。判定阶段开始时,你选择一项:⒈使用此牌对应的实体牌,然后本阶段不能再使用此牌名的牌;⒉将所有的“蓄谋”牌置入弃牌堆。', diff --git a/character/mobile.js b/character/mobile.js index 37218e870..c7a38fd83 100644 --- a/character/mobile.js +++ b/character/mobile.js @@ -6,7 +6,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ connect:true, characterSort:{ mobile:{ - mobile_default:['mb_chengui','mb_huban','mb_xianglang','yanxiang','xin_wuban','laimin','baoxin','jiangji','liwei','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",'shichangshi'], + mobile_default:['xin_huojun','muludawang','mb_chengui','mb_huban','mb_xianglang','yanxiang','xin_wuban','laimin','baoxin','jiangji','liwei','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",'shichangshi'], mobile_yijiang:["yj_zhanghe","yj_zhangliao","yj_xuhuang","yj_ganning",'yj_huangzhong','yj_weiyan','yj_zhoubuyi'], mobile_standard:["xin_xiahoudun","xin_zhangfei"], mobile_shenhua_feng:['re_xiaoqiao',"xin_zhoutai"], @@ -26,6 +26,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, character:{ + xin_huojun:['male','shu',4,['sidai','jieyu'],['character:tw_huojun','die_audio:tw_huojun']], + muludawang:['male','qun','3/3/1',['shoufa','yuxiang','zhoulin']], mb_chengui:['male','qun',3,['guimou','zhouxian']], mb_huban:['male','wei',4,['mbyilie']], mb_xianglang:['male','shu',3,['naxue','yijie']], @@ -176,6 +178,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ scs_gaowang:['male','qun','',['scsmiaoyu'],['unseen','sex:male_castrated']], }, characterIntro:{ + muludawang:'古典小说《三国演义》中的虚构人物,八纳洞主,孟获盟友。擅驱兽法,能行风雨,控制猛兽并指挥它们作战。在法术帮助下最初对蜀军取得一些胜利,但在诸葛亮的喷火木兽将他的动物吓跑后战败,最后死于乱军之中。', laimin:'来敏(165年—261年),字敬达,义阳新野人,东汉太中大夫来歙之后,司空来艳之子,三国时期蜀汉官员。东汉末年,逢董卓之乱,来敏跟随姐夫黄琬到荆州避难,黄琬是刘璋祖母的侄子,来敏又与姐姐来氏入蜀,被刘璋引为宾客。来敏喜欢读书,尤其喜欢《左氏春秋》。刘备平定益州后,以来敏为典学校尉,后立太子,来敏为家令。刘禅继位后,任命来敏为虎贲中郎将,诸葛亮驻汉中,请来敏为军祭酒、辅军将军。却因其口出狂言而被罢官,诸葛亮死后,来敏历任大长秋、光禄大夫、执慎将军等职,期间多次因说错话而被免官,蜀汉景耀年间,来敏去世,时年九十七岁。', shichangshi:'十常侍,指中国东汉(公元25年—220年)灵帝时期(168年-189年)操纵政权的十二个宦官:张让、赵忠、夏恽、郭胜、孙璋、毕岚、栗嵩、段珪、高望、张恭、韩悝、宋典(在小说《三国演义》里,十常侍指的是指张让、赵忠、封谞、段珪、曹节、侯览、蹇硕、程旷、夏恽、郭胜十人),他们都任职中常侍。玩弄小皇帝于股掌之中,以至灵帝称“张常侍是我父,赵常侍是我母”。十常侍自己横征暴敛,卖官鬻爵,他们的父兄子弟遍布天下,横行乡里,祸害百姓,无官敢管。人民不堪剥削、压迫,纷纷起来反抗。当时一些比较清醒的官吏,已看出宦官集团的黑暗腐败,导致大规模农民起义的形势。郎中张钧在给皇帝的奏章中明确指出,黄巾起义是外戚宦官专权逼出来的,他说:“张角所以能兴兵作乱,万人所以乐附之者,其源皆由十常侍多放父兄、子弟、婚宗、宾客典据州郡,辜确财利,侵略百姓,百姓之怨无所告诉,故谋议不轨,聚为‘盗贼’。”后被曹操、袁绍所歼。', sunzhang:'孙璋(?-189年?)东汉末期汉灵帝的宦官,官居中常侍,为十常侍之一,在张让、赵忠之下位居第三。光熹元年(189年),张让、赵忠、段珪等诛杀何进,袁绍率军入宫,诛杀孙璋。', @@ -391,6 +394,257 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, skill:{ + //霍骏 + sidai:{ + audio:'twsidai', + enable:'phaseUse', + usable:1, + locked:false, + limited:true, + skillAnimation:true, + animationColor:'fire', + filter:function(event,player){ + var cards=player.getCards('h',{type:'basic'}); + if(!cards.length) return false; + for(var i of cards){ + if(!game.checkMod(i,player,'unchanged','cardEnabled2',player)) return false; + } + return event.filterCard(get.autoViewAs({name:'sha',storage:{sidai:true}},cards),player,event); + }, + viewAs:{name:'sha',storage:{sidai:true}}, + filterCard:{type:'basic'}, + selectCard:-1, + check:()=>1, + onuse:function(result,player){ + player.awakenSkill('sidai'); + player.addTempSkill('sidai_tao'); + player.addTempSkill('sidai_shan'); + }, + ai:{ + order:function(item,player){ + return get.order({name:'sha'},player)+0.1; + }, + result:{ + target:function(player,target){ + var cards=ui.selected.cards.slice(0); + var names=[]; + for(var i of cards) names.add(i.name); + if(names.length=0) return -20; + return lib.card.sha.ai.result.target.apply(this,arguments); + }, + }, + }, + subSkill:{ + tao:{ + trigger:{source:'damageSource'}, + filter:function(event,player){ + if(!event.card||!event.card.storage||!event.card.storage.sidai||!event.player.isIn()) return false; + for(var i of event.cards){ + if(i.name=='tao') return true; + } + return false; + }, + forced:true, + popup:false, + content:function(){ + trigger.player.loseMaxHp(); + }, + }, + shan:{ + trigger:{player:'useCardToPlayered'}, + filter:function(event,player){ + if(!event.card||!event.card.storage||!event.card.storage.sidai||!event.target.isIn()) return false; + for(var i of event.cards){ + if(i.name=='shan') return true; + } + return false; + }, + forced:true, + popup:false, + content:function(){ + 'step 0' + trigger.target.chooseToDiscard('h',{type:'basic'},'弃置一张基本牌,否则不能响应'+get.translation(trigger.card)).set('ai',function(card){ + var player=_status.event.player; + if(player.hasCard('hs',function(cardx){ + return cardx!=card&&get.name(cardx,player)=='shan'; + })) return 12-get.value(card); + return 0; + }); + 'step 1' + if(!result.bool) trigger.directHit.add(trigger.target); + }, + }, + }, + }, + jieyu:{ + audio:'twjieyu', + trigger:{player:'phaseJieshuBegin'}, + filter:function(event,player){ + for(let i=0;i1?'牌名各不相同的':'')+'基本牌'; + }, + async content(event,trigger,player){ + const num=lib.skill.jieyu.getNum(player,event); + let gains=[],names=[]; + for(let i=0;i=0;i--){ + const evt=history[i]; + if(evt.name=='jieyu'&&evt.player==player){ + if(!event||evt!=event) break; + } + if(evt.name=='useCard'&&evt.player!=player&&evt.targets&&evt.targets.includes(player)&&get.tag(evt.card,'damage')){ + num--; + if(num==1) break; + } + } + return num; + }, + }, + //木鹿大王 + shoufa:{ + audio:2, + trigger:{ + player:'damageEnd', + source:'damageSource', + }, + filter:function(event,player,name){ + if(name=='damageSource'&&player.getHistory('sourceDamage').indexOf(event)!=0) return false; + return game.hasPlayer(target=>{ + if(name=='damageEnd') return get.distance(player,target)>2; + return get.distance(player,target)<=2; + }); + }, + direct:true, + async content(event,trigger,player){ + const zhoufa=player.storage.zhoulin_zhoufa; + const str=zhoufa?[ + '令其受到1点无来源伤害', + '你随机获得其一张牌', + '你随机弃置其装备区的一张牌', + '令其摸一张牌', + ][['豹','鹰','熊','兔'].indexOf(zhoufa)]:'令其随机执行一个效果'; + const {result:{bool,targets}}=await player.chooseTarget(get.prompt('shoufa'),'选择一名距离'+(event.triggername=='damageEnd'?'':'不')+'大于2的角色,'+str,(card,player,target)=>{ + const name=_status.event.name; + if(name=='damageEnd'&&get.distance(player,target)<=2) return false; + if(name=='damageSource'&&get.distance(player,target)>2) return false; + const zhoufa=player.storage.zhoulin_zhoufa; + if(!zhoufa) return true; + if(zhoufa=='豹'||zhoufa=='兔') return true; + if(zhoufa=='鹰') return target.countCards('he'); + return target.countDiscardableCards(player,'e'); + }).set('ai',target=>{ + const player=_status.event.player; + const zhoufa=player.storage.zhoulin_zhoufa; + if(!zhoufa) return -get.attitude(player,target); + switch(zhoufa){ + case '豹': + return get.damageEffect(target,player,player); + case '鹰': + return get.effect(target,{name:'guohe_copy2'},player,player); + case '熊': + let att=get.attitude(player,target),eff=0; + target.getCards('e',card=>{ + var val=get.value(card,target); + eff=Math.max(eff,-val*att); + }); + return eff; + case '兔': + return get.effect(target,{name:'draw'},player,player); + } + }).set('name',event.triggername); + if(!bool) return; + const target=targets[0]; + player.logSkill('shoufa',target); + const shoufa=zhoufa?zhoufa:['豹','鹰','熊','兔'].randomGet(); + game.log(target,'执行','#g'+shoufa,'效果'); + switch(shoufa){ + case '豹': + target.damage('nosource'); + break; + case '鹰': + player.gain(target.getGainableCards(player,'he'),target,'giveAuto'); + break; + case '熊': + target.discard(target.getGainableCards(player,'e').randomGet()).discarder=player; + break; + case '兔': + target.draw(); + break; + } + }, + }, + yuxiang:{ + mod:{ + globalFrom(from,to,distance){ + if(from.hujia>0) return distance-1; + }, + globalTo(from,to,distance){ + if(to.hujia>0) return distance+1; + }, + }, + audio:true, + trigger:{player:'damageBegin2'}, + filter:function(event,player){ + return player.hujia>0&&event.hasNature('fire'); + }, + forced:true, + async content(event,trigger,player){ + trigger.num++; + }, + }, + zhoulin:{ + audio:2, + limited:true, + unique:true, + enable:'phaseUse', + skillAnimation:true, + animationColor:'fire', + async content(event,trigger,player){ + player.awakenSkill('zhoulin'); + player.changeHujia(2,null,true); + const {result:{control}}=await player.chooseControl('豹','鹰','熊','兔').set('ai',()=>'豹').set('prompt','选择一个固定效果'); + if(control){ + player.popup(control); + game.log(player,'选择了','#g'+control,'效果'); + player.addTempSkill('zhoulin_zhoufa'); + player.storage.zhoulin_zhoufa=control; + player.markSkill('zhoulin_zhoufa'); + game.broadcastAll(function(player,zhoufa){ + if(player.marks.zhoulin_zhoufa) player.marks.zhoulin_zhoufa.firstChild.innerHTML=zhoufa; + },player,control); + } + }, + ai:{ + order:12, + result:{player:1}, + }, + subSkill:{ + zhoufa:{ + charlotte:true, + onremove:true, + intro:{content:'已选择$效果'}, + }, + } + }, //陈珪 guimou:{ audio:2, @@ -15380,6 +15634,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ mobilexingxue:function(player){ return lib.translate[(player.storage.mobileyanzhu?'mobilexingxuex':'mobilexingxue')+'_info']; }, + shoufa:function(player){ + const zhoufa=player.storage.zhoulin_zhoufa; + if(!zhoufa) return '当你受到伤害后/于一回合首次造成伤害后,你可以选择一名与你距离大于/不大于2的角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。'; + let str='当你受到伤害后/于一回合首次造成伤害后,你可以选择一名与你距离大于/不大于2的角色,'; + str+=[ + '令其受到1点无来源伤害', + '你随机获得其一张牌', + '你随机弃置其装备区的一张牌', + '令其摸一张牌', + ][['豹','鹰','熊','兔'].indexOf(zhoufa)]; + return str; + }, }, perfectPair:{ simazhao:['simayi','jin_simayi','jin_wangyuanji'], @@ -16247,6 +16513,19 @@ game.import('character',function(lib,game,ui,get,ai,_status){ mbyilie2:'义烈', mbyilie3:'义烈', mbyilie_info:'锁定技。①游戏开始时,你选择一名其他角色,然后你获得以下效果:其受到伤害时,若你的“烈”标记数小于2,则你获得等同于伤害值的“烈”标记,然后防止此伤害;其对其他角色造成伤害后,你回复1点体力。②结束阶段,若你有“烈”标记,你摸X张牌并失去X点体力,然后移去所有“烈”标记(X为你拥有的“烈”标记数)。', + muludawang:'木鹿大王', + shoufa:'兽法', + shoufa_info:'当你受到伤害后/于一回合首次造成伤害后,你可以选择一名与你距离大于/不大于2的角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。', + yuxiang:'御象', + yuxiang_info:'锁定技,若你有护甲值,则:①你计算与其他角色的距离-1,其他角色计算与你的距离+1;②当你受到火焰伤害时,此伤害+1。', + zhoulin:'咒鳞', + zhoulin_info:'限定技,出牌阶段,你可以获得2点护甲值,然后选择一个“兽法”效果,你发动〖兽法〗的执行效果改为你选择的效果直到你的下个回合结束。', + xin_huojun:'手杀霍峻', + xin_huojun_prefix:'手杀', + sidai:'伺怠', + sidai_info:'限定技,出牌阶段,你可以将手牌区内的所有基本牌当做【杀】使用。若此牌对应的实体牌中:包含【闪】,则目标角色成为此牌的目标后,需弃置一张基本牌,否则不可响应此牌;包含【桃】,则当目标角色受到此牌的伤害后,其减1点体力上限。', + jieyu:'竭御', + jieyu_info:'结束阶段,你可以从弃牌堆中获得共X张不同牌名的基本牌(X为3-你上次发动〖竭御〗至今你成为其他角色使用伤害类卡牌目标的次数,且X至少为1)。', mobile_standard:'手杀异构·标准包', mobile_shenhua_feng:'手杀异构·其疾如风', diff --git a/character/rank.js b/character/rank.js index be84b750e..4848518f3 100644 --- a/character/rank.js +++ b/character/rank.js @@ -130,6 +130,7 @@ window.noname_character_rank={ 'sb_guanyu', 'mb_chengui', 'jsrg_guozhao', + 'sb_caopi', ], a:[ 'diy_zaozhirenjun', @@ -359,6 +360,7 @@ window.noname_character_rank={ 'jsrg_zhugeliang', ], am:[ + 'muludawang', 'diy_caiwenji', 'diy_liuyan', 'diy_zhenji', @@ -656,6 +658,7 @@ window.noname_character_rank={ 'jsrg_zhangxuan', ], bp:[ + 'xin_huojun', 'chess_diaochan', 'chess_huangzhong', 'chess_sunshangxiang', @@ -1032,6 +1035,7 @@ window.noname_character_rank={ 'jsrg_weiwenzhugezhi', ], b:[ + 'liyi', 'diy_feishi', 'diy_liufu', 'diy_tianyu', @@ -2104,6 +2108,8 @@ window.noname_character_rank={ 'dc_sb_zhouyu', ], rare:[ + 'xin_huojun', + 'muludawang', 'mb_huban', 'sp_jianggan', 'ol_caozhang', diff --git a/character/refresh.js b/character/refresh.js index 71930bb29..31492b4ce 100755 --- a/character/refresh.js +++ b/character/refresh.js @@ -4434,9 +4434,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ effect:{ target:(card,player,target)=>{ if(!get.tag(card,'damage')) return; - if(target.hp+target.hujia<2||player.hasSkillTag('jueqing',false,target)) return -2; + if(target.hp+target.hujia<2||player.hasSkillTag('jueqing',false,target)) return 2; if(target.countMark('redanxin')>1) return [1,1]; - return [1,Math.min(2,0.8*target.hp-0.7)]; + return [1,0.8*target.hp-0.4]; } } } @@ -14332,8 +14332,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ effect:{ target:function(card,player,target){ if(!target.hasFriend()) return; - if(get.tag(card,'damage')==1&&target.hp==3&&!target.isTurnedOver()&& + if(target.hp===3&&get.tag(card,'damage')==1&&!target.isTurnedOver()&& _status.currentPhase!=target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [0.5,1]; + if(target.hp===1&&get.tag(card,'recover')&&!target.isTurnedOver()&& + _status.currentPhase!==target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [1,-3]; } } } diff --git a/character/sb.js b/character/sb.js index be73a07b3..8f30a4ca6 100644 --- a/character/sb.js +++ b/character/sb.js @@ -5,6 +5,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ name:'sb', connect:true, character:{ + sb_caopi:['male','wei',3,['sbxingshang','sbfangzhu','sbsongwei'],['zhu']], sb_guanyu:['male','shu',4,['sbwusheng','sbyijue']], sb_huangyueying:['female','shu',3,['sbjizhi','sbqicai']], sb_sp_zhugeliang:['male','shu',3,['sbhuoji','sbkanpo']], @@ -55,6 +56,392 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, skill:{ + //曹丕 + sbxingshang:{ + audio:2, + trigger:{global:['die','damageEnd']}, + usable:1, + forced:true, + locked:false, + async content(event,trigger,player){ + player.addMark('sbxingshang',1); + }, + marktext:'颂', + intro:{ + name:'颂', + content:'mark', + }, + ai:{threaten:2.5}, + group:'sbxingshang_use', + subSkill:{ + use:{ + audio:'sbxingshang', + enable:'phaseUse', + filter:function(event,player){ + return game.hasPlayer(target=>{ + if(player.countMark('sbxingshang')>1) return true; + return player.countMark('sbxingshang')&&(target.isLinked()||target.isTurnedOver()); + }); + }, + usable:1, + chooseButton:{ + dialog:function(){ + var dialog=ui.create.dialog( + '行殇:请选择你要执行的一项', + [[ + [1,'   ⒈复原一名角色的武将牌   '], + [2,'   ⒉令一名角色摸'+Math.min(5,Math.max(1,game.dead.length))+'张牌   '], + ],'tdnodes'], + [[ + [3,'   ⒊令一名体力上限小于10的角色加1点体力上限并回复1点体力,然后随机恢复一个被废除的装备栏   '], + ],'tdnodes'], + [[ + [4,'   ⒋获得一名已阵亡角色的所有技能,然后失去武将牌上的所有技能   '], + ],'tdnodes'] + ); + return dialog; + }, + filter:function(button,player){ + if(button.link>player.countMark('sbxingshang')) return false; + switch(button.link){ + case 1: + return game.hasPlayer(target=>target.isLinked()||target.isTurnedOver()); + case 2: + return true; + case 3: + return game.hasPlayer(target=>target.maxHp<10); + case 4: + return game.dead.length; + } + }, + check:function(button){ + let player=_status.event.player; + switch(button.link){ + case 1: + return game.filterPlayer(current=>get.attitude(player,current)>0).reduce((list,target)=>{ + let num=0; + if(target.isLinked()) num+=0.5; + if(target.isTurnedOver()) num+=10; + list.push(num); + return list; + },[]).sort((a,b)=>b-a)[0]; + case 2: + return Math.min(5,Math.max(1,game.dead.length)); + case 3: + return game.filterPlayer().reduce((list,target)=>{ + list.push(get.recoverEffect(target,player,player)); + return list; + },[]).sort((a,b)=>b-a)[0]; + case 4: + return game.dead.reduce((list,target)=>{ + let num=0; + if(target.name&&lib.character[target.name]) num+=get.rank(target.name,true); + if(target.name2&&lib.character[target.name2]) num+=get.rank(target.name2,true); + list.push(num); + return list; + },[]).sort((a,b)=>b-a)[0]; + } + }, + backup:function(links,player){ + return { + num:links[0], + audio:'sbxingshang', + filterTarget:function(card,player,target){ + switch(lib.skill.sbxingshang_use_backup.num){ + case 1: + return target=>target.isLinked()||target.isTurnedOver(); + case 2: + return true; + case 3: + return target.maxHp<10; + case 4: + return target==player; + } + }, + selectTarget:()=>lib.skill.sbxingshang_use_backup.num==4?-1:1, + async content(event,trigger,player){ + const target=event.targets[0]; + const num=lib.skill.sbxingshang_use_backup.num; + player.removeMark('sbxingshang',num); + switch(num){ + case 1: + if(target.isLinked()) target.link(false); + if(target.isTurnedOver()) target.turnOver(); + break; + case 2: + target.draw(Math.min(5,Math.max(1,game.dead.length))); + break; + case 3: + target.gainMaxHp(); + target.recover(); + let list=[]; + for (let i=1;i<=5;i++){ + if(target.hasDisabledSlot(i)) list.push('equip'+i); + } + if(list.length) target.enableEquip(list.randomGet()); + break; + case 4: + let map={}; + game.dead.forEach(target=>map[target.playerid]=get.translation(target)); + const {result:{control}}=await player.chooseControl(Object.values(map)).set('ai',()=>{ + const getNum=(target)=>{ + let num=0; + if(target.name&&lib.character[target.name]) num+=get.rank(target.name,true); + if(target.name2&&lib.character[target.name2]) num+=get.rank(target.name2,true); + return num; + }; + let controls=_status.event.controls.slice(); + controls=controls.map(name=>[name,game.dead.find(target=>_status.event.map[target.playerid]==name)]); + controls.sort((a,b)=>getNum(b[1])-getNum(a[1])); + return controls[0][0]; + }).set('prompt','获得一名已阵亡角色的所有技能').set('map',map); + if(control){ + const target2=game.dead.find(targetx=>map[targetx.playerid]==control); + player.line(target2); + game.log(player,'选择了',target2); + const skills=target2.getStockSkills(true,true); + const skills2=player.getStockSkills(true,true); + player.addSkillLog(skills); + player.removeSkillLog(skills2); + } + } + }, + ai:{ + result:{ + target:function(player,target){ + switch(lib.skill.sbxingshang_use_backup.num){ + case 1: + let num=0; + if(target.isLinked()) num+=0.5; + if(target.isTurnedOver()) num+=10; + return num; + case 2: + return 1; + case 3: + return get.recoverEffect(target,player,player); + case 4: + return 1; + } + }, + }, + }, + } + }, + prompt:function(links,player){ + switch(links[0]){ + case 1: + return '复原一名角色的武将牌'; + case 2: + return '令一名角色摸'+get.cnNumber(Math.min(5,Math.max(1,game.dead.length)))+'张牌'; + case 3: + return '令一名体力上限小于10的角色加1点体力上限并回复1点体力,然后随机恢复一个被废除的装备栏'; + case 4: + return '获得一名已阵亡角色的所有技能,然后失去武将牌上的所有技能'; + } + } + }, + ai:{ + order:9, + result:{player:1}, + }, + }, + use_backup:{}, + }, + }, + sbfangzhu:{ + audio:2, + enable:'phaseUse', + filter:function(event,player){ + return player.countMark('sbxingshang')>1; + }, + usable:1, + chooseButton:{ + dialog:function(){ + var dialog=ui.create.dialog('放逐:请选择你要执行的一项','hidden'); + dialog.add([[ + [1,'移去2个“颂”标记,令一名其他角色的非Charlotte技能失效直到其回合结束'], + [2,'移去2个“颂”标记,令一名其他角色不能响应除其外的角色使用的牌直到其回合结束'], + [3,'移去3个“颂”标记,令一名其他角色将武将牌翻面'], + [4,'移去3个“颂”标记,令一名其他角色只能使用你选择的一种类型的牌直到其回合结束'] + ],'textbutton']); + return dialog; + }, + filter:function(button,player){ + if(button.link>2&&player.countMark('sbxingshang')<3) return false; + if(button.link==4) return game.hasPlayer(target=>target!=player&&!target.hasSkill('sbfangzhu_ban')); + return true; + }, + check:function(button){ + let player=_status.event.player; + switch(button.link){ + case 1: + return game.filterPlayer(current=>get.attitude(player,current)<0).reduce((list,target)=>{ + let num=0; + if(target.name&&lib.character[target.name]) num+=get.rank(target.name,true); + if(target.name2&&lib.character[target.name2]) num+=get.rank(target.name2,true); + list.push(num); + return list; + },[]).sort((a,b)=>b-a)[0]; + case 2: + return 0; + case 3: + return game.filterPlayer(target=>target!=player&&!target.hasSkill('sbfangzhu_ban')).reduce((list,target)=>{ + if(get.attitude(player,target)>0&&target.isTurnedOver()) list.push(10*target.countCards('hs')+1); + else if(get.attitude(player,target)<0&&!target.isTurnedOver()) list.push(5*target.countCards('hs')+1); + else list.push(0); + return list; + },[]).sort((a,b)=>b-a)[0]; + case 4: + return 0; + } + }, + backup:function(links,player){ + return { + num:links[0], + audio:'sbfangzhu', + filterTarget:lib.filter.notMe, + async content(event,trigger,player){ + const target=event.target; + const num=lib.skill.sbfangzhu_backup.num; + player.removeMark('sbxingshang',num>2?3:2); + switch(num){ + case 1: + target.removeSkill('baiban'); + target.addTempSkill('baiban',{player:'phaseEnd'}); + break; + case 2: + target.addTempSkill('sbfangzhu_kill',{player:'phaseEnd'}); + break; + case 3: + target.turnOver(); + break; + case 4: + const {result:{control}}=await player.chooseControl('basic','trick','equip').set('ai',()=>'equip').set('prompt','放逐:请选择'+get.translation(target)+'仅能使用的类别的牌'); + if(control){ + player.line(target); + player.popup(get.translation(control)+'牌'); + target.addTempSkill('sbfangzhu_ban',{player:'phaseEnd'}); + target.markAuto('sbfangzhu_ban',[control]); + } + } + }, + ai:{ + result:{ + target:function(player,target){ + switch(lib.skill.sbfangzhu_backup.num){ + case 1: + let num=0; + if(target.name&&lib.character[target.name]) num+=get.rank(target.name,true); + if(target.name2&&lib.character[target.name2]) num+=get.rank(target.name2,true); + return num; + case 2: + return 0; + case 3: + if(get.attitude(player,target)>0&&target.isTurnedOver()) return 10*target.countCards('hs')+1; + if(get.attitude(player,target)<0&&!target.isTurnedOver()) return -5*target.countCards('hs')+1; + return 0; + case 4: + return 0; + } + }, + }, + }, + } + }, + prompt:function(links,player){ + switch(links[0]){ + case 1: + return '移去2个“颂”标记,令一名其他角色的非Charlotte技能失效直到其回合结束'; + case 2: + return '移去2个“颂”标记,令一名其他角色不能响应除其外的角色使用的牌直到其回合结束'; + case 3: + return '移去3个“颂”标记,令一名其他角色将武将牌翻面'; + case 4: + return '移去3个“颂”标记,令一名其他角色只能使用你选择的一种类型的牌直到其回合结束'; + } + } + }, + ai:{ + order:9, + result:{player:1}, + }, + subSkill:{ + backup:{}, + kill:{ + charlotte:true, + mark:true, + marktext:'禁', + intro:{content:'不能响应其他角色使用的牌'}, + trigger:{global:'useCard1'}, + filter:function(event,player){ + return event.player!=player; + }, + forced:true, + popup:false, + async content(event,trigger,player){ + trigger.directHit.add(player); + }, + }, + ban:{ + charlotte:true, + onremove:true, + mark:true, + marktext:'禁', + intro:{ + markcount:()=>0, + content:'只能使用$牌', + }, + mod:{ + cardEnabled:function(card,player){ + if(!player.getStorage('sbfangzhu_ban').includes(get.type2(card))) return false; + }, + cardSavable:function(card,player){ + if(!player.getStorage('sbfangzhu_ban').includes(get.type2(card))) return false; + }, + }, + }, + }, + }, + sbsongwei:{ + audio:2, + trigger:{player:'phaseUseBegin'}, + filter:function(event,player){ + return game.hasPlayer(target=>target.group=='wei'&&target!=player); + }, + zhuSkill:true, + forced:true, + locked:false, + async content(event,trigger,player){ + player.addMark('sbxingshang',game.countPlayer(target=>target.group=='wei'&&target!=player)); + }, + group:'sbsongwei_delete', + subSkill:{ + delete:{ + audio:'sbsongwei', + enable:'phaseUse', + filter:function(event,player){ + return game.hasPlayer(target=>lib.skill.sbsongwei.subSkill.delete.filterTarget(null,player,target)); + }, + filterTarget:function(card,player,target){ + return target!=player&&target.group=='wei'&&target.getStockSkills(false,true).length; + }, + skillAnimation:true, + animationColor:'thunder', + async content(event,trigger,player){ + player.awakenSkill('sbsongwei_delete'); + event.target.removeSkillLog(event.target.getStockSkills(false,true)); + }, + ai:{ + order:13, + result:{ + target:function(player,target){ + return -target.getStockSkills(false,true).length; + }, + }, + }, + }, + }, + }, //关羽 //矢 sbwusheng:{ @@ -254,19 +641,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, filter:function(event,player){ - if(!game.hasPlayer(target=>target!=player&&target.hasEmptySlot(2))) return false; return player.countCards('h',card=>lib.skill.sbqicai.filterCardx(card,player))||event.sbqicai&&event.sbqicai.length; }, filterCardx:function(card,player){ - if(player.getStorage('sbqicai').includes(card.name)) return false; - return get.type(card)=='equip'&&get.subtype(card)=='equip2'; + //if(player.getStorage('sbqicai').includes(card.name)) return false; + return get.type(card)=='equip'&&get.hasPlayer(target=>target!=player&&target.hasEmptySlot(get.subtype(card))); }, usable:1, chooseButton:{ dialog:function(event,player){ const list1=player.getCards('h',card=>lib.skill.sbqicai.filterCardx(card,player)); const list2=event.sbqicai; - var dialog=ui.create.dialog('###奇才###
请选择一张防具牌置入一名其他角色的装备区
'); + var dialog=ui.create.dialog('###奇才###
请选择一张装备牌置入一名其他角色的装备区
'); if(list1.length){ dialog.add('
手牌区
'); dialog.add(list1); @@ -281,7 +667,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ check:function(button){ var player=_status.event.player; var num=get.value(button.link); - if(!game.hasPlayer(target=>target!=player&&target.hasEmptySlot(2)&&get.attitude(player,target)>0)) num=1/(get.value(button.link)||0.5); + if(!game.hasPlayer(target=>target!=player&&target.hasEmptySlot(get.subtype(button.link))&&get.attitude(player,target)>0)) num=1/(get.value(button.link)||0.5); if(get.owner(button.link)) return num; return num*5; }, @@ -310,7 +696,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ target.$gain2(cards); game.delayx(); } - player.markAuto('sbqicai',[cards[0].name]); + //player.markAuto('sbqicai',[cards[0].name]); target.equip(cards[0]); player.addSkill('sbqicai_gain'); lib.skill.sbqicai.updateCounter(player,target,0); @@ -556,7 +942,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sbkanpo:{ init:function(player){ if(!player.storage.sbkanpo){ - player.storage.sbkanpo=[3,[],[]]; + player.storage.sbkanpo=[4,[],[]]; player.markSkill('sbkanpo'); } }, @@ -655,7 +1041,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ const event=get.event(); if(!event.isMine()) return; if(button.classList.contains('selectable')==false) return; - if(ui.selected.buttons.length>=lib.skill.sbkanpo.getNumber) return false; + if(ui.selected.buttons.length>=sum) return false; button.classList.add('selected'); ui.selected.buttons.push(button); let counterNode=button.querySelector('.caption'); @@ -1822,7 +2208,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ })):0,alter=[null,1,1],temp; for(let i of game.players){ if(player===i) continue; - let vplayer=new lib.element.Player(i); + let vplayer=ui.create.player(i); temp=get.effect(i,new lib.element.VCard({name:'juedou',isCard:true}),vplayer,i); vplayer.remove(); if(temp){ @@ -5951,7 +6337,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sbhuoji:'火计', sbhuoji_info:'使命技。①使命:出牌阶段限一次。你可以对一名其他角色造成1点火焰伤害,然后你对所有与其势力相同的不为其的其他角色各造成1点火焰伤害。②成功:准备阶段,若你本局游戏已造成的火焰伤害不小于本局游戏总角色数,则你失去〖火计〗和〖看破〗,然后获得〖观星〗和〖空城〗。③失败:使命成功前进入濒死状态。', sbkanpo:'看破', - sbkanpo_info:'①一轮游戏开始时,你清除〖看破①〗记录的牌名,然后你可以依次记录任意个未于上次发动〖看破①〗记录清除过的非装备牌牌名(对其他角色不可见,每局游戏至多记录3个牌名)。②其他角色使用你〖看破①〗记录过的牌名的牌时,你可以移去一个〖看破①〗中的此牌名的记录令此牌无效,然后你摸一张牌。', + sbkanpo_info:'①一轮游戏开始时,你清除〖看破①〗记录的牌名,然后你可以依次记录任意个未于上次发动〖看破①〗记录清除过的非装备牌牌名(对其他角色不可见,每局游戏至多记录4个牌名)。②其他角色使用你〖看破①〗记录过的牌名的牌时,你可以移去一个〖看破①〗中的此牌名的记录令此牌无效,然后你摸一张牌。', sbguanxing:'观星', sbguanxing_info:'①准备阶段,你将所有“星”置入弃牌堆,将牌堆顶的X张牌置于你的武将牌上,称为“星”(X为7-此前发动〖观星①〗次数的三倍,且X至少为0)。然后你可以将任意张“星”置于牌堆顶。②结束阶段,若你未于本回合的准备阶段将“星”置于过牌堆顶,你可以将任意张“星”置于牌堆顶。③你可以如手牌般使用或打出“星”。', sbkongcheng:'空城', @@ -5960,7 +6346,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sb_huangyueying_prefix:'谋', sbqicai:'奇才', sbqicai_backup:'奇才', - sbqicai_info:'①出牌阶段限一次。你可以将手牌中或弃牌堆中的一张防具牌置于一名其他角色的防具栏,然后其获得如下效果:当其得到普通锦囊牌后,其将此牌交给你(限三张)。②你使用锦囊牌无距离限制。', + sbqicai_info:'①出牌阶段限一次。你可以将手牌中或弃牌堆中的一张装备牌置于一名其他角色的对应装备栏,然后其获得如下效果:当其得到普通锦囊牌后,其将此牌交给你(限三张)。②你使用锦囊牌无距离限制。', sbjizhi:'集智', sbjizhi_info:'锁定技,当你使用一张普通锦囊牌时,你摸一张牌,且此牌本回合不计入你的手牌上限。', sb_guanyu:'谋关羽', @@ -5970,6 +6356,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sbwusheng_info:'你可以将一张手牌当作任意【杀】使用或打出。出牌阶段开始时,你可以选择一名非主公的其他角色,本阶段对其使用【杀】无距离和次数限制,使用【杀】指定其为目标后摸一张牌,对其使用五张【杀】后不能对其使用【杀】。', sbyijue:'义绝', sbyijue_info:'锁定技,每名角色每局游戏限一次,当你对一名角色造成大于等于其体力值的伤害时,你防止此伤害,且本回合你使用牌指定其为目标后,取消之。', + sb_caopi:'谋曹丕', + sb_caopi_prefix:'谋', + sbxingshang:'行殇', + sbxingshang_info:'①每回合限一次,当一名角色死亡时或受到伤害时,你获得1个“颂”标记。②出牌阶段限一次,你可以:1.移去1个“颂”标记,令一名角色复原武将牌;2.移去2个“颂”标记,令一名角色摸X张牌(X为场上阵亡角色数,且X至少为1,至多为5);3.移去3个“颂”标记,令一名体力上限小于10的角色加1点体力上限,回复1点体力,随机恢复一个已废除的装备栏;4.移去4个“颂”标记,获得一名阵亡角色武将牌上的所有技能,然后你失去武将牌上的所有技能。', + sbfangzhu:'放逐', + sbfangzhu_info:'出牌阶段限一次,你可以:1.移去2个“颂”标记,令一名其他角色的非Charlotte技能失效直到其回合结束;2.移去2个“颂”标记,令一名其他角色不能响应除其以为的角色使用的牌直到其回合结束;3.移去2个“颂”标记,令一名其他角色将武将牌翻面;4.移去2个“颂”标记,令一名其他角色只能使用你选择的一种类型的牌直到其回合结束。', + sbsongwei:'颂威', + sbsongwei_info:'主公技。①出牌阶段开始时,你获得Y个“颂”标记(Y为场上其他魏势力角色数)。②每局游戏限一次,出牌阶段,你可以令一名其他魏势力角色失去所有武将牌的技能。', sb_zhi:'谋攻篇·知', sb_shi:'谋攻篇·识', diff --git a/character/shenhua.js b/character/shenhua.js index 222262139..412fc771f 100755 --- a/character/shenhua.js +++ b/character/shenhua.js @@ -414,20 +414,31 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return target!=player&&target.countCards('he')>0; }, ai1:function(card){ - var player=_status.event.player; - var num=player.getExpansions('olkongsheng').length,hs=player.countCards('h'); - if(get.position(card)!='e') hs--; - if(hs==num&&player.isDamaged()&&get.recoverEffect(player,player,player)>0) return 9-get.value(card); + let player=_status.event.player; + if(_status.event.me){ + if(get.position(card)===_status.event.me) return 12-player.hp-get.value(card); + return 0; + } return 5-get.value(card); }, ai2:function(target){ - var player=_status.event.player; - var has=target.hasCard(function(card){ + let player=_status.event.player,att=get.attitude(player,target); + if(att>0&&(_status.event.me||target.isHealthy())) return -att; + if(att>0&&(target.countCards('he')>target.hp||target.hasCard(function(card){ return get.value(card,target)<=0; - },'e'),att=get.attitude(player,target); - if(!has) att=-att; - return att*has?2:1; + },'e'))) return att; + return -att; }, + me:function(){ + if(player.isHealthy()||get.recoverEffect(player,player,_status.event.player)<=0) return false; + let ph=player.countCards('h'),num=player.getExpansions('olkongsheng').length; + if(ph===num){ + if(player.hasSkillTag('noh')) return 'h'; + return 'e'; + } + if(ph-1===num) return 'h'; + return false; + }() }); 'step 1' if(result.bool){ @@ -3823,8 +3834,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ effect:{ target:function(card,player,target){ if(!target.hasFriend()) return; - if(get.tag(card,'damage')==1&&target.hp==2&&!target.isTurnedOver()&& - _status.currentPhase!=target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [0.5,1]; + if(target.hp===2&&get.tag(card,'damage')==1&&!target.isTurnedOver()&& + _status.currentPhase!==target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [0.5,1]; + if(target.hp===1&&get.tag(card,'recover')&&!target.isTurnedOver()&& + _status.currentPhase!==target&&get.distance(_status.currentPhase,target,'absolute')<=3) return [1,-3]; } } } @@ -7705,7 +7718,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ re_yuanshao:['re_yuanshao','ol_yuanshao','xin_yuanshao','sb_yuanshao'], pangde:['re_pangde','ol_pangde','pangde'], yanwen:['yanwen','ol_yanwen','re_yanwen'], - caopi:['caopi','re_caopi','ps_caopi'], + caopi:['caopi','re_caopi','ps_caopi','sb_caopi'], xuhuang:['re_xuhuang','ol_xuhuang','sb_xuhuang','xuhuang'], menghuo:['menghuo','re_menghuo','sb_menghuo'], zhurong:['zhurong','ol_zhurong','re_zhurong','sb_zhurong'], diff --git a/character/sp.js b/character/sp.js index 5627da30a..bf0e5e12a 100755 --- a/character/sp.js +++ b/character/sp.js @@ -8,7 +8,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sp_tianji:["sunhao","liuxie","caoang","hetaihou","sunluyu",'ol_wangrong',"zuofen","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','caoxi'], sp_tianzhu:['zhangyan','niujin','hejin','hansui',"wutugu","yanbaihu","shamoke","zhugedan",'huangzu','gaogan',"tadun","fanjiangzhangda","ahuinan","dongtuna",'ol_wenqin'], - sp_nvshi:["lingju","guanyinping","zhangxingcai","mayunlu","dongbai","zhaoxiang",'ol_zhangchangpu',"daxiaoqiao","jin_guohuai"], + sp_nvshi:['ol_dingshangwan',"lingju","guanyinping","zhangxingcai","mayunlu","dongbai","zhaoxiang",'ol_zhangchangpu',"daxiaoqiao","jin_guohuai"], sp_shaowei:["simahui","zhangbao","zhanglu","zhugeguo","xujing","zhangling",'huangchengyan','zhangzhi','lushi'], 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','ol_qianzhao'], sp_liesi:['lvboshe','mizhu','weizi','ol_liuba','zhangshiping'], @@ -18,7 +18,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ sp_zhongdan:["cuiyan","huangfusong"], sp_guozhan2:["sp_dongzhuo","liqueguosi","zhangren"], sp_others:["hanba","caiyang"], - sp_waitforsort:['ol_luyusheng','ol_pengyang','ol_tw_zhangji','ol_dingshangwan','ol_liwan','ol_liuyan','caoyu'], + sp_waitforsort:['ol_luyusheng','ol_pengyang','ol_tw_zhangji','ol_liwan','ol_liuyan','caoyu','liyi'], }, }, characterFilter:{ @@ -30,6 +30,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, character:{ + liyi:['male','wu',4,['olchanshuang','olzhanjin']], caoyu:['male','wei',3,['olgongjie','olxiangxv','olxiangzuo']], ol_liwan:['female','wei',3,['ollianju','olsilv']], ol_dingshangwan:['female','wei',3,['olfudao','olfengyan']], @@ -202,6 +203,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ luzhi:['male','wei',3,['qingzhong','weijing']] }, characterIntro:{ + liyi:'李异(生卒年不详),三国时期东吴将领。建安末,与谢旌率水陆三千,击破刘备军将领詹晏、陈凤。刘备领兵攻孙权时,李异与陆逊等人屯巫、秭归,为蜀将所破。黄武元年(222年),陆逊破刘备于猇亭,李异追踪蜀军,屯驻南山。清代学者赵一清认为此李异与刘璋部将李异为同一人。', caoyu:'曹宇(?-278年),字彭祖,沛国谯县(今安徽亳州)人。三国时期魏国宗室,魏武帝曹操与环夫人之子,邓哀王曹冲同母兄弟。太和六年,封为燕王。魏明帝病危,欲以大将军辅政,不果。其子常道乡公曹奂,是魏国末代皇帝,史称魏元帝。晋朝建立后,降封燕公。咸宁四年(278年),曹宇去世。', zhangyan:'张燕,本姓褚,生卒年不详,常山真定(今河北正定南)人,东汉末年黑山军首领。张燕剽捍,敏捷过人,军中称为“飞燕”。官渡之战时投降曹操,被任命为平北将军,封安国亭侯。死后其子张方袭爵。', lushi:'卢氏,五斗米教主张衡妻,张鲁母,擅长驻颜之术,常年令自己保持少女的容颜。常拜访刘焉,与其交好。', @@ -705,6 +707,207 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, skill:{ + //李异 + olchanshuang:{ + audio:2, + enable:'phaseUse', + filterTarget:lib.filter.notMe, + usable:1, + content:function*(event,map){ + const player=map.player,target=event.target; + const choiceList=[ + '重铸一张牌', + '使用一张【杀】', + '弃置两张牌', + ],list=['重铸','出杀','弃牌','无法选择']; + let result=[]; + for(let current of [player,target]){ + let list1=list.slice(),choiceList1=choiceList.slice(); + list1=list1.filter(control=>{ + if(control=='无法选择') return false; + if(control=='重铸') return current.countCards('he',card=>current.canRecast(card)); + if(control=='出杀') return current.countCards('he',card=>card.name=='sha'&¤t.hasUseTarget(card)); + if(control=='弃牌') return current.countCards('he',card=>lib.filter.cardDiscardable(card,current))>1; + }); + choiceList1=choiceList.filter(control=>{ + if(choiceList.indexOf(control)==0) return current.countCards('he',card=>current.canRecast(card)); + if(choiceList.indexOf(control)==1) return current.countCards('he',card=>card.name=='sha'&¤t.hasUseTarget(card)); + if(choiceList.indexOf(control)==2) return current.countCards('he',card=>lib.filter.cardDiscardable(card,current))>1; + }); + if(list1.length){ + if(list1.length==1) result.push(list.indexOf(list1[0])); + else{ + let result1=yield current.chooseControl(list1).set('ai',()=>{ + const current=_status.event.player; + const controls=_status.event.controls.slice(); + if(controls.includes('出杀')&¤t.countCards('hs',card=>card.name=='sha'&¤t.hasValueTarget(card))) return '出杀'; + if(controls.includes('重铸')) return '重铸'; + return '弃牌'; + }).set('choiceList',choiceList1); + if(result1.control) result.push(list.indexOf(result1.control)); + } + } + else result.push(3); + } + player.popup(list[result[0]]); + target.popup(list[result[1]]); + for(let current of [player,target]){ + switch(list[result[current==player?0:1]]){ + case '重铸': + let result2=yield current.chooseCard('he','请重铸一张牌',(card,player)=>player.canRecast(card),true); + if(result2.bool) current.recast(result2.cards); + break; + case '出杀': + current.chooseToUse({ + prompt:'请使用一张【杀】', + filterCard:function(card,player){ + if(card.name!='sha') return false; + return lib.filter.filterCard.apply(this,arguments); + }, + forced:true, + ai1:function(card){ + return _status.event.player.getUseValue(card); + }, + }); + break; + case '弃牌': + current.chooseToDiscard('he',2,true); + break; + } + } + }, + ai:{ + order:function(item,player){ + return get.order({name:'sha'},player)-0.1; + }, + result:{ + target:function(player,target){ + const att=get.attitude(player,target); + if(target.countCards('hs',card=>{ + return card.name=='sha'&&game.hasPlayer(current=>{ + return target.canUse(card,current)&&get.effect(current,card,target,target)>0&&get.effect(current,card,target,player)>0; + }); + })) return 3; + if(att>0) return 2; + if(!target.countCards('h')) return get.sgn(att)+(att==0?1:0); + return 0; + }, + }, + }, + group:'olchanshuang_end', + subSkill:{ + end:{ + audio:'olchanshuang', + trigger:{player:'phaseJieshuBegin'}, + filter:function(event,player){ + return player.getHistory('lose',evt=>{ + if(evt.type=='discard'){ + var evtx=evt.getl(player); + return evtx&&evtx.cards2.length==2; + } + return evt.getParent(2).name=='recast'; + }).length||player.getHistory('useCard',evt=>evt.card.name=='sha').length; + }, + forced:true, + locked:false, + content:function*(event,map){ + let num=0,player=map.player; + if(player.getHistory('lose',evt=>evt.getParent(2).name=='recast').length) num++; + if(player.getHistory('useCard',evt=>evt.card.name=='sha').length) num++; + if(player.getHistory('lose',evt=>{ + if(evt.type=='discard'){ + var evtx=evt.getl(player); + return evtx&&evtx.cards2.length==2; + } + }).length) num++; + if(num&&player.countCards('he',card=>player.canRecast(card))){ + let result=yield player.chooseCard('he','请重铸一张牌',(card,player)=>player.canRecast(card),true); + if(result.bool) yield player.recast(result.cards); + } + if(num>1&&player.countCards('he',card=>card.name=='sha'&&player.hasUseTarget(card))){ + yield player.chooseToUse({ + prompt:'请使用一张【杀】', + filterCard:function(card,player){ + if(card.name!='sha') return false; + return lib.filter.filterCard.apply(this,arguments); + }, + forced:true, + ai1:function(card){ + return _status.event.player.getUseValue(card); + }, + }); + } + if(num>2&&player.countCards('he',card=>lib.filter.cardDiscardable(card,player))) yield player.chooseToDiscard('he',2,true); + }, + }, + }, + }, + olzhanjin:{ + audio:2, + locked:true, + group:'olzhanjin_guanshi', + subSkill:{ + guanshi:{ + audio:'olzhanjin', + nobracket:true, + equipSkill:true, + trigger:{player:['shaMiss','eventNeutralized']}, + filter:function(event,player){ + if(!player.hasEmptySlot(1)||!lib.card.guanshi) return false; + if(event.type!='card'||event.card.name!='sha'||!event.target.isIn()) return false; + return player.countCards('he')>=2; + }, + direct:true, + locked:false, + content:function(){ + "step 0" + player.chooseToDiscard(get.prompt('olzhanjin_guanshi'),'弃置两张牌,令'+get.translation(trigger.card)+'强制命中',2,'he').set('ai',function(card){ + var evt=_status.event.getTrigger(); + if(get.attitude(evt.player,evt.target)<0){ + if(player.needsToDiscard()) return 15-get.value(card); + if(evt.baseDamage+evt.extraDamage>=Math.min(2,evt.target.hp)) return 8-get.value(card); + return 5-get.value(card); + } + return -1; + }).set('complexCard',true).logSkill='olzhanjin_guanshi'; + 'step 1' + if(result.bool){ + if(event.triggername=='shaMiss'){ + trigger.untrigger(); + trigger.trigger('shaHit'); + trigger._result.bool=false; + trigger._result.result=null; + } + else trigger.unneutralize(); + } + }, + mod:{ + attackRange:function(player,num){ + if(lib.card.guanshi&&player.hasEmptySlot(1)) return num-lib.card.guanshi.distance.attackFrom; + }, + }, + ai:{ + directHit_ai:true, + skillTagFilter:function(player,tag,arg){ + if(player._olzhanjin_guanshi_temp||!player.hasEmptySlot(1)||!lib.card.guanshi) return; + player._guanshi_temp=true; + var bool=(get.attitude(player,arg.target)<0&&arg.card&&arg.card.name=='sha'&&player.countCards('he',card=>{ + return card!=arg.card&&(!arg.card.cards||!arg.card.cards.includes(card))&&get.value(card)<5; + })>1); + delete player._olzhanjin_guanshi_temp; + return bool; + }, + effect:{ + target:function(card,player,target){ + if(player==target&&get.subtype(card)=='equip1'){ + if(get.equipValue(card)<=get.equipValue({name:'guanshi'})) return 0; + } + }, + }, + }, + }, + }, + }, //曹宇 olgongjie:{ audio:2, @@ -764,12 +967,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } return cards.length-player.countCards('h')>0; }, + usable:1, logTarget:()=>_status.currentPhase, async content(event,trigger,player){ - player.tempBanSkill('olxiangxv',null,false); player.when({global:'phaseEnd'}).then(()=>{ if(target&&target.isIn()){ - var num=target.countCards('h')!=player.countCards('h'); + var num=target.countCards('h')-player.countCards('h'); if(num){ if(num>0){ if(player.countCards('h')<5) player.draw(Math.min(5-player.countCards('h'),num)); @@ -2399,7 +2602,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ evt.set('olqifan',true); var cards=get.bottomCards(lib.skill.olqifan.getNum(),true); var aozhan=player.hasSkill('aozhan'); - player.chooseButton(['器翻:选择要使用的牌',cards]).set('filterButton',function(button){ + player.chooseButton(['嚣翻:选择要使用的牌',cards]).set('filterButton',function(button){ return _status.event.cards.includes(button.link); }).set('cards',cards.filter(function(card){ if(aozhan&&card.name=='tao'){ @@ -2483,7 +2686,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(hs>0) player.chooseToDiscard(hs,pos,true); event.num++; if(event.numevt.card==event.card).length&&!['delay','equip'].includes(get.type(event.cards[0],player)); + }).length&&player.getHistory('sourceDamage',evt=>evt.card==event.card).length&&player.hasUseTarget(event.cards[0]); }, direct:true, content:function(){ - var card={ - name:get.name(trigger.cards[0],player), - nature:get.nature(trigger.cards[0],player), - isCard:true, - }; - player.chooseUseTarget(card,get.prompt('dcjiaoxia'),false,false).set('prompt2','视为使用'+get.translation(card)).logSkill='dcjiaoxia'; + player.chooseUseTarget(trigger.cards[0],get.prompt('dcjiaoxia'),false,false).set('prompt2','使用'+get.translation(card)).logSkill='dcjiaoxia'; }, }, }, @@ -5335,10 +5330,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ reliewei:{ audio:'liewei', trigger:{global:'dying'}, - frequent:true, filter:function(event,player){ - return player==_status.currentPhase; + return player==_status.currentPhase||player.getHistory('useSkill',evt=>evt.skill=='reliewei').length1); + }).set('goon',player.needsToDiscard()||player.getExpansions('twxingwu').length>1); 'step 1' if(result.bool){ player.logSkill('twxingwu'); @@ -8658,7 +8658,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ai:{ effect:{ player:function(card,player,target){ - if(target.hasMark('twlvren')) return 0.33; + if(target&&target.hasMark('twlvren')) return 0.33; } } }, diff --git a/character/xianding.js b/character/xianding.js index a958de99c..6c9672f95 100644 --- a/character/xianding.js +++ b/character/xianding.js @@ -2654,7 +2654,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcjianguo:{ audio:2, enable:'phaseUse', - usable:1, + filter:function(event,player){ + return !player.hasSkill('dcjianguo_0')||!player.hasSkill('dcjianguo_1'); + }, chooseButton:{ dialog:function(event,player){ var dialog=ui.create.dialog('谏国:请选择一项','hidden'); @@ -2664,6 +2666,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ ],'textbutton']); return dialog; }, + filter:function(button,player){ + if(button.link=='discard'&&player.hasSkill('dcjianguo_0')) return false; + if(button.link=='draw'&&player.hasSkill('dcjianguo_1')) return false; + return true; + }, check:function(button){ var player=_status.event.player; if(button.link=='discard'){ @@ -2701,6 +2708,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, subSkill:{ + '0':{charlotte:true}, + '1':{charlotte:true}, backup:{audio:'dcjianguo'}, discard:{ audio:'dcjianguo', @@ -2709,16 +2718,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){ selectCard:-1, content:function(){ 'step 0' + player.addTempSkill('dcjianguo_0','phaseUseAfter'); target.draw(); game.delayex(); 'step 1' - var num=Math.floor(target.countCards('h')/2); + var num=Math.ceil(target.countCards('h')/2); if(num>0) target.chooseToDiscard(num,true,'谏国:请弃置'+get.cnNumber(num)+'张手牌'); }, ai:{ result:{ target:function(player,target){ - return 1.1-Math.ceil(target.countCards('h')/2); + return 1.1-Math.floor(target.countCards('h')/2); }, }, tag:{ @@ -2736,9 +2746,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){ selectCard:-1, content:function(){ 'step 0' + player.addTempSkill('dcjianguo_1','phaseUseAfter'); target.chooseToDiscard('he',true,'谏国:请弃置一张牌'); 'step 1' - var num=Math.floor(target.countCards('h')/2); + var num=Math.ceil(target.countCards('h')/2); if(num>0) target.draw(num); }, ai:{ @@ -2747,7 +2758,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var fix=0; var num=target.countCards('h'); if(player==target&&num%2==1&&num>=5) fix+=1; - return Math.floor(num/2-0.5)+fix; + return Math.ceil(num/2-0.5)+fix; }, }, tag:{ @@ -2813,15 +2824,18 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, //甘糜 dcchanjuan:{ - audio:2, - trigger:{ - player:'useCardAfter', + init:function(player){ + if(!player.storage.dcchanjuan){ + player.storage.dcchanjuan={}; + } }, + audio:2, + trigger:{player:'useCardAfter'}, filter:function(event,player){ if(event.targets.length!=1) return false; if(!['basic','trick'].includes(get.type(event.card,false))) return false; if(event.getParent(2).name=='dcchanjuan') return false; - return !player.getStorage('dcchanjuan').includes(event.card.name); + return !player.storage.dcchanjuan[event.card.name]||player.storage.dcchanjuan[event.card.name]<2; }, direct:true, content:function(){ @@ -2834,17 +2848,28 @@ game.import('character',function(lib,game,ui,get,ai,_status){ player.chooseUseTarget(card,get.prompt('dcchanjuan'),false,false).set('prompt2','视为再使用一张'+get.translation(card)).set('logSkill','dcchanjuan'); 'step 1' if(result.bool){ - player.markAuto('dcchanjuan',[trigger.card.name]); + if(!player.storage.dcchanjuan[trigger.card.name]) player.storage.dcchanjuan[trigger.card.name]=0; + player.storage.dcchanjuan[trigger.card.name]++; var list1=trigger.targets,list2=result.targets; if(list1.slice().removeArray(list2).length==0&&list2.slice().removeArray(list1).length==0) player.draw(); } }, - ai:{ - threaten:2, - }, + ai:{threaten:2}, + mark:true, intro:{ - content:'已记录牌名:$', - } + markcount:(storage)=>0, + content:function(storage){ + var str='已使用牌名:',names=Object.keys(storage); + if(!names.length) str+='无'; + else names.forEach(name=>{ + str+='
  • 【'; + str+=get.translation(name); + str+='】:'; + str+=storage[name]+'次'; + }); + return str; + }, + }, }, dcxunbie:{ audio:2, @@ -3695,16 +3720,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ complexCard:true, selectCard:[1,4], position:'he', - filterCard:function(card,player){ - var suit=get.suit(card); - if(!lib.suit.includes(suit)) return false; - if(ui.selected.cards.length){ - if(ui.selected.cards.some(i=>{ - return get.suit(i)==suit; - })) return false; - } - return true; - }, + filterCard:true, check:function(card){ var player=_status.event.player; var suit=get.suit(card); @@ -3728,22 +3744,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, ai:{ order:2, - result:{ - player:function(player){ - var suits=lib.suit.filter(suit=>{ - return player.countCards('h',{suit:suit})>1; - }); - var suits2=[],cards=player.getCards('h'); - for(var card of cards){ - var suitx=get.suit(card); - if(suits2.includes(suitx)) continue; - if(!player.hasCard(cardx=>cardx!=card&&get.suit(cardx)==suitx)&&get.value(card)<7.5||get.value(card)<6) suits2.add(suitx); - } - if(suits2.length<=suits.length) return 0; - return 1; - } - } - } + result:{player:1}, + }, }, dchuayi:{ audio:2, @@ -3761,16 +3763,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ trigger:{global:'phaseEnd'}, charlotte:true, forced:true, - filter:function(event,player){ - return event.player!=player; - }, content:function(){ player.draw(); }, mark:true, intro:{ name:'华衣·红', - content:'其他角色的回合结束时,你摸一张牌' + content:'一名角色的回合结束时,你摸一张牌' }, }, black:{ @@ -4324,10 +4323,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){ audio:2, trigger:{player:'phaseUseBegin'}, filter:function(event,player){ - var card=lib.skill.dcshexue.getLast(); - return card&&player.hasUseTarget(card,false); + var cards=lib.skill.dcshexue.getLast(); + return cards.some(card=>player.hasUseTarget(card,false)); }, getLast:function(){ + var cards=[]; for(var current of game.filterPlayer()){ var history=current.actionHistory; if(history.length<2) continue; @@ -4337,18 +4337,22 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var evt=evts[i]; if(get.type(evt.card)!='basic'&&get.type(evt.card)!='trick') continue; var evtx=evt.getParent('phaseUse'); - if(evtx&&evtx.player==current){ - return {name:evt.card.name,nature:evt.card.nature}; - } + if(evtx&&evtx.player==current) cards.push({name:evt.card.name,nature:evt.card.nature}); } } } - return null; + return cards; }, direct:true, group:'dcshexue_end', content:function(){ - var card=lib.skill.dcshexue.getLast(); + 'step 0' + var cards=lib.skill.dcshexue.getLast(); + cards=cards.filter(card=>player.hasUseTarget(card,false)); + player.chooseButton(['设学:是否将一张牌当作其中一张牌使用?',[cards,'vards']]); + 'step 1' + if(!result.bool) return; + var card=result.links[0]; game.broadcastAll(function(card){ lib.skill.dcshexue_backup.viewAs=card; },card); @@ -4384,11 +4388,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }).length; }, prompt2:function(event,player){ - var history=player.getHistory('useCard',evt=>{ - return evt.getParent('phaseUse')==event&&(get.type(evt.card)=='basic'||get.type(evt.card)=='trick'); - }); - var card=history[history.length-1].card; - return '令下一回合的角色于其出牌阶段开始时选择是否将一张牌当做'+(get.translation(card.nature)||'')+'【'+get.translation(card.name)+'】使用'; + return '令下一回合的角色于其出牌阶段开始时选择是否将一张牌当做你本阶段使用过的一张基本牌或普通锦囊牌使用?'; }, check:function(event,player){ let evt=event.getParent('phase').getParent(); @@ -4402,11 +4402,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ var history=player.getHistory('useCard',evt=>{ return evt.getParent('phaseUse')==trigger&&(get.type(evt.card)=='basic'||get.type(evt.card)=='trick'); }); - var card=history[history.length-1].card; - card={name:card.name,nature:card.nature}; player.addSkill('dcshexue_studyclear'); if(!player.storage.dcshexue_studyclear) player.storage.dcshexue_studyclear=[]; - player.storage.dcshexue_studyclear.push(card); + history.forEach(evt=>{ + var card=evt.card; + card={name:card.name,nature:card.nature}; + player.storage.dcshexue_studyclear.push(card); + }); } }, study:{ @@ -9180,7 +9182,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, }, huaping:{ - audio:'huaping', + audio:2, trigger:{global:'die'}, limited:true, skillAnimation:true, @@ -13857,7 +13859,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcjinjie:'尽节', dcjinjie_info:'当一名角色进入濒死状态时,可以令其摸一张牌。然后若你本轮未进行过回合,你可以弃置X张手牌令其回复1点体力(X为本轮你发动过〖尽节〗的次数)。', dcjue:'举讹', - dcjue_info:'准备阶段,你可以视为对一名未受伤的角色使用一张【杀】。', + dcjue_info:'准备阶段,你可以视为对一名体力值或手牌数大于你的角色使用一张【杀】。', dc_tengfanglan:'滕芳兰', dcluochong:'落宠', dcluochong_info:'一轮游戏开始时,你可以弃置任意名角色区域里的共计至多[4]张牌,然后若你以此法弃置了一名角色的至少三张牌,则你方括号内的数字-1。', @@ -13895,7 +13897,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcquanshou:'劝守', dcquanshou_info:'一名角色的回合开始时,若其手牌数不大于其体力上限,你可以令其选择一项:1.将手牌摸至体力上限,然后本回合使用【杀】的次数上限-1(至多摸五张);2.其本回合使用牌被抵消后,你摸一张牌。', dcshexue:'设学', - dcshexue_info:'①出牌阶段开始时,你可以将一张牌当做上回合的角色于其出牌阶段内使用的最后一张基本牌或普通锦囊牌使用。②出牌阶段结束时,你可以令下回合的角色于其出牌阶段开始时可以将一张牌当做你于此阶段内使用的最后一张基本牌或普通锦囊牌使用(一名角色因〖设学〗使用的牌均无距离和次数限制)。', + dcshexue_info:'①出牌阶段开始时,你可以将一张牌当做上回合的角色于其出牌阶段内使用的一张基本牌或普通锦囊牌使用。②出牌阶段结束时,你可以令下回合的角色于其出牌阶段开始时可以将一张牌当做你于此阶段内使用的一张基本牌或普通锦囊牌使用(一名角色因〖设学〗使用的牌均无距离和次数限制)。', xizheng:'郤正', dcdanyi:'耽意', dcdanyi_info:'当你使用牌指定第一个目标后,你可以摸X张牌(X为此牌目标数与你使用的上一张牌相同的目标数)。', @@ -13908,9 +13910,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcjijiao_info:'限定技。出牌阶段,你可以令一名角色获得所有弃牌堆中你于本局游戏内使用或弃置过的普通锦囊牌,且这些牌不能被【无懈可击】响应。一名角色的回合结束后,若本回合牌堆洗过牌或有角色死亡,你重置〖继椒〗。', duanqiaoxiao:'段巧笑', dccaizhuang:'彩妆', - dccaizhuang_info:'出牌阶段限一次。你可以弃置任意张花色各不相同的牌。然后若你手牌中的花色数小于你以此法弃置的牌数,你摸一张牌并重复此流程。', + dccaizhuang_info:'出牌阶段限一次。你可以弃置任意张牌。然后若你手牌中的花色数小于你以此法弃置的牌数,你摸一张牌并重复此流程。', dchuayi:'华衣', - dchuayi_info:'结束阶段,你可以判定,然后你获得如下效果直到你下回合开始时:红色,其他角色回合结束时,你摸一张牌;黑色,当你受到伤害后,你摸两张牌。', + dchuayi_info:'结束阶段,你可以判定,然后你获得如下效果直到你下回合开始时:红色,一名角色的回合结束时,你摸一张牌;黑色,当你受到伤害后,你摸两张牌。', wu_zhugeliang:'武诸葛亮', wu_zhugeliang_prefix:'武', dcjincui:'尽瘁', @@ -13927,8 +13929,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcjiudun:'酒遁', dcjiudun_info:'①以你为目标的【酒】(使用方法①)的作用效果改为“目标对应的角色使用的下一张【杀】的伤害基数+1”。②当你成为其他角色使用黑色牌的目标后,若你:未处于【酒】状态,你可以摸一张牌并视为使用一张【酒】;处于【酒】状态,你可以弃置一张手牌令此牌对你无效。', ganfurenmifuren:'甘夫人糜夫人', - dcchanjuan:'婵娟', - dcchanjuan_info:'每种牌名限一次。当你使用仅指定单一目标的【杀】或普通锦囊牌结算结束后,你可以视为使用一张名称和属性均相同的牌。若这两张牌指定的目标完全相同,你摸一张牌。', + dcchanjuan:'双姝', + dcchanjuan_info:'每种牌名限两次。当你使用仅指定单一目标的【杀】或普通锦囊牌结算结束后,你可以视为使用一张名称和属性均相同的牌。若这两张牌指定的目标完全相同,你摸一张牌。', dcxunbie:'殉别', dcxunbie_info:'限定技。当你进入濒死状态时,你可以将此武将牌替换为“甘夫人”或“糜夫人”(不能选择已在场上的武将)。然后回复至1点体力并防止所有伤害直到当前回合结束。', dc_mifuren:'糜夫人', @@ -13945,7 +13947,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ dcshenzhi_info:'准备阶段,若你的手牌数大于体力值,你可以弃置一张手牌,然后回复1点体力。', dc_duyu:'杜预', dcjianguo:'谏国', - dcjianguo_info:'出牌阶段限一次。你可以选择一名角色并选择一项:1.令其摸一张牌,然后其弃置一半的手牌;2.令其弃置一张牌,然后其摸等同于手牌数一半的牌(均向下取整)。', + dcjianguo_info:'出牌阶段各限一次。你可以选择一名角色并选择一项:1.令其摸一张牌,然后其弃置一半的手牌;2.令其弃置一张牌,然后其摸等同于手牌数一半的牌(均向上取整)。', dcdyqingshi:'倾势', dcdyqingshi_info:'当你于回合内使用【杀】或普通锦囊牌指定第一个目标后,若目标角色包括其他角色且此牌为你本回合使用的第X张牌,你可以对其中一名不为你的目标角色造成1点伤害(X为你的手牌数)。', sunlingluan:'孙翎鸾', diff --git a/character/yijiang.js b/character/yijiang.js index 17b91c55f..516fdbe34 100755 --- a/character/yijiang.js +++ b/character/yijiang.js @@ -5958,6 +5958,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){ } }, intro:{content:'【矫诏】加成等级:Lv.#'}, + ai:{ + maixie:true, + effect:{ + target:(card,player,target)=>{ + if(!get.tag(card,'damage')) return; + if(target.hp+target.hujia<2||player.hasSkillTag('jueqing',false,target)) return 1.8; + if(target.countMark('xindanxin')>1) return [1,1]; + return [1,0.8*target.hp-0.5]; + } + } + } }, danxin:{ trigger:{player:'damageEnd'}, @@ -5998,7 +6009,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ effect:{ target:(card,player,target)=>{ if(!get.tag(card,'damage')) return; - if(target.hp<2||player.hasSkillTag('jueqing',false,target)) return -1.5; + if(target.hp<2||player.hasSkillTag('jueqing',false,target)) return 1.5; return [1,1]; } } @@ -8067,60 +8078,41 @@ game.import('character',function(lib,game,ui,get,ai,_status){ audio:2, trigger:{player:'phaseJieshuBegin'}, direct:true, - content:function(){ - 'step 0' + async content(event,trigger,player){ var num=player.hp; if(!player.hasSkill('yanzhu')){ num=player.maxHp; } - player.chooseTarget([1,num],get.prompt2('xingxue')).set('ai',function(target){ + const {result:{targets,bool}}= + await player.chooseTarget([1,num],get.prompt2('xingxue')).set('ai',function(target){ var att=get.attitude(_status.event.player,target); if(target.countCards('he')) return att; return att/10; }); - 'step 1' - if(result.bool){ - player.logSkill('xingxue',result.targets); - event.targets=result.targets; - event.targets.sort(lib.sort.seat); + if(bool){ + player.logSkill('xingxue',targets); + const chooseToPutCard = async function(target){ + await target.draw(); + if(target.countCards('he')){ + const {result:{cards,bool}} = + await target.chooseCard('选择一张牌置于牌堆顶','he',true); + if(bool){ + await target.lose(cards,ui.cardPile,'insert'); + } + game.broadcastAll(function(player){ + var cardx=ui.create.card(); + cardx.classList.add('infohidden'); + cardx.classList.add('infoflip'); + player.$throw(cardx,1000,'nobroadcast'); + },target); + if(player == game.me){ + game.delay(0.5); + } + } + }; + await game.doAsyncInOrder(targets,chooseToPutCard); } - else{ - event.finish(); - } - 'step 2' - if(event.targets.length){ - var target=event.targets.shift(); - target.draw(); - event.current=target; - } - else{ - event.finish(); - } - 'step 3' - if(event.current&&event.current.countCards('he')){ - event.current.chooseCard('选择一张牌置于牌堆顶','he',true); - } - else{ - event.goto(2); - } - 'step 4' - if(result&&result.cards){ - event.card=result.cards[0]; - event.current.lose(result.cards,ui.cardPile,'insert'); - game.broadcastAll(function(player){ - var cardx=ui.create.card(); - cardx.classList.add('infohidden'); - cardx.classList.add('infoflip'); - player.$throw(cardx,1000,'nobroadcast'); - },event.current); - } - else{ - event.card=null; - } - 'step 5' - if(event.current==game.me) game.delay(0.5); - event.goto(2); - } + }, }, yanzhu:{ audio:2, diff --git a/game/asset.js b/game/asset.js index f8670e51a..0d0ce7d8a 100644 --- a/game/asset.js +++ b/game/asset.js @@ -1,5 +1,5 @@ window.noname_asset_list=[ - 'v1.10.6', + 'v1.10.6.1', /*audio start*/ 'audio/background/aozhan_chaoming.mp3', 'audio/background/aozhan_online.mp3', @@ -7237,30 +7237,41 @@ window.noname_asset_list=[ 'image/character/jsp_liubei.jpg', 'image/character/jsp_zhaoyun.jpg', 'image/character/jsrg_caocao.jpg', + 'image/character/jsrg_caofang.jpg', 'image/character/jsrg_chendeng.jpg', 'image/character/jsrg_chunyuqiong.jpg', 'image/character/jsrg_dongbai.jpg', 'image/character/jsrg_fanjiangzhangda.jpg', + 'image/character/jsrg_gaoxiang.jpg', 'image/character/jsrg_guanyu.jpg', 'image/character/jsrg_guojia.jpg', + 'image/character/jsrg_guoxun.jpg', + 'image/character/jsrg_guozhao.jpg', 'image/character/jsrg_hansui.jpg', 'image/character/jsrg_hejin.jpg', 'image/character/jsrg_huangfusong.jpg', 'image/character/jsrg_huangzhong.jpg', + 'image/character/jsrg_jiangwei.jpg', 'image/character/jsrg_kongrong.jpg', 'image/character/jsrg_liubei.jpg', 'image/character/jsrg_liuhong.jpg', 'image/character/jsrg_liuyan.jpg', + 'image/character/jsrg_liuyong.jpg', 'image/character/jsrg_lougui.jpg', + 'image/character/jsrg_luxun.jpg', 'image/character/jsrg_lvbu.jpg', 'image/character/jsrg_machao.jpg', 'image/character/jsrg_nanhualaoxian.jpg', 'image/character/jsrg_pangtong.jpg', 'image/character/jsrg_qiaoxuan.jpg', + 'image/character/jsrg_simayi.jpg', 'image/character/jsrg_sunce.jpg', 'image/character/jsrg_sunjian.jpg', + 'image/character/jsrg_sunjun.jpg', + 'image/character/jsrg_sunlubansunluyu.jpg', 'image/character/jsrg_sunshangxiang.jpg', 'image/character/jsrg_wangyun.jpg', + 'image/character/jsrg_weiwenzhugezhi.jpg', 'image/character/jsrg_xiahouen.jpg', 'image/character/jsrg_xiahourong.jpg', 'image/character/jsrg_xugong.jpg', @@ -7272,7 +7283,10 @@ window.noname_asset_list=[ 'image/character/jsrg_zhanghe.jpg', 'image/character/jsrg_zhangliao.jpg', 'image/character/jsrg_zhangren.jpg', + 'image/character/jsrg_zhangxuan.jpg', + 'image/character/jsrg_zhaoyun.jpg', 'image/character/jsrg_zhenji.jpg', + 'image/character/jsrg_zhugeliang.jpg', 'image/character/jsrg_zhujun.jpg', 'image/character/jsrg_zoushi.jpg', 'image/character/jun_caocao.jpg', diff --git a/game/keyWords.js b/game/keyWords.js index 7acfae8e7..a1b8fe1c1 100644 --- a/game/keyWords.js +++ b/game/keyWords.js @@ -1,3 +1,3 @@ -window.bannedKeyWords=[ -'ghs','直肠','性交','做爱','http','吃奶','骚逼','哈巴狗','美眉','癌','屁眼','艹','傻逼','操你','做鸡','奸','姦','华为','屄','狗子','屎','同性恋','肖战','鸡巴','精液','粪水','挂月亮中','贱骨头','吃屁','傻','奥利给','丁真','蛆','鼠鼠','鼠人','神友','', -]; \ No newline at end of file +window.bannedKeyWords=JSON.parse( + decodeURIComponent( + atob("JTVCJTIyZ2hzJTIyJTJDJTIyJUU3JTlCJUI0JUU4JTgyJUEwJTIyJTJDJTIyJUU2JTgwJUE3JUU0JUJBJUE0JTIyJTJDJTIyJUU1JTgxJTlBJUU3JTg4JUIxJTIyJTJDJTIyaHR0cCUyMiUyQyUyMiVFNSU5MCU4MyVFNSVBNSVCNiUyMiUyQyUyMiVFOSVBQSU5QSVFOSU4MCVCQyUyMiUyQyUyMiVFNSU5MyU4OCVFNSVCNyVCNCVFNyU4QiU5NyUyMiUyQyUyMiVFNyVCRSU4RSVFNyU5QyU4OSUyMiUyQyUyMiVFNyU5OSU4QyUyMiUyQyUyMiVFNSVCMSU4MSVFNyU5QyVCQyUyMiUyQyUyMiVFOCU4OSVCOSUyMiUyQyUyMiVFNSU4MiVCQiVFOSU4MCVCQyUyMiUyQyUyMiVFNiU5MyU4RCVFNCVCRCVBMCUyMiUyQyUyMiVFNSU4MSU5QSVFOSVCOCVBMSUyMiUyQyUyMiVFNSVBNSVCOCUyMiUyQyUyMiVFNSVBNyVBNiUyMiUyQyUyMiVFNSU4RCU4RSVFNCVCOCVCQSUyMiUyQyUyMiVFNSVCMSU4NCUyMiUyQyUyMiVFNyU4QiU5NyVFNSVBRCU5MCUyMiUyQyUyMiVFNSVCMSU4RSUyMiUyQyUyMiVFNSU5MCU4QyVFNiU4MCVBNyVFNiU4MSU4QiUyMiUyQyUyMiVFOCU4MiU5NiVFNiU4OCU5OCUyMiUyQyUyMiVFOSVCOCVBMSVFNSVCNyVCNCUyMiUyQyUyMiVFNyVCMiVCRSVFNiVCNiVCMiUyMiUyQyUyMiVFNyVCMiVBQSVFNiVCMCVCNCUyMiUyQyUyMiVFNiU4QyU4MiVFNiU5QyU4OCVFNCVCQSVBRSVFNCVCOCVBRCUyMiUyQyUyMiVFOCVCNCVCMSVFOSVBQSVBOCVFNSVBNCVCNCUyMiUyQyUyMiVFNSU5MCU4MyVFNSVCMSU4MSUyMiUyQyUyMiVFNSU4MiVCQiUyMiUyQyUyMiVFNSVBNSVBNSVFNSU4OCVBOSVFNyVCQiU5OSUyMiUyQyUyMiVFNCVCOCU4MSVFNyU5QyU5RiUyMiUyQyUyMiVFOCU5QiU4NiUyMiUyQyUyMiVFOSVCQyVBMCVFOSVCQyVBMCUyMiUyQyUyMiVFOSVCQyVBMCVFNCVCQSVCQSUyMiUyQyUyMiVFNyVBNSU5RSVFNSU4RiU4QiUyMiUyQyUyMiUzQyUyRmElM0UlMjIlNUQ="))); \ No newline at end of file diff --git a/game/update.js b/game/update.js index 7c18fdd0b..4be954e40 100644 --- a/game/update.js +++ b/game/update.js @@ -1,137 +1,56 @@ window.noname_update={ - version:'1.10.6', - update:'1.10.5', + version:'1.10.6.1', + update:'1.10.6', changeLog:[ - '整合@nonameShijian @mengxinzxz @PZ157 @Ansolve @Rintim @S-N-O-R-L-A-X @universe-st @copcap @kuangshen04 的Pull Request', - '拆分game.js,优化代码逻辑与可读性', - '孙策(十周年斗地主)、乐小乔、手杀陈珪、手杀胡班、OL界凌统、OL界曹彰、OL界简雍、OL谋姜维、谋诸葛亮、谋关羽、曹宇、星董卓、曹宪、新杀谋鲁肃、新杀谋周瑜', + '整合@mengxinzxz @PZ157 @universe-st @Ansolve @Rintim @nonameShijian @copcap @kuangshen04 的Pull Request', + '《江山如故·合》武将包', '其他AI优化与bug修复', ], files:[ - 'card/extra.js', - 'card/gujian.js', - 'card/guozhan.js', - 'card/gwent.js', - 'card/hearth.js', - 'card/huanlekapai.js', - 'card/mtg.js', - 'card/sp.js', 'card/standard.js', - 'card/swd.js', - 'card/yingbian.js', 'card/yongjian.js', - 'card/yunchou.js', - 'card/zhenfa.js', - 'card/zhulu.js', - 'character/clan.js', - 'character/collab.js', - 'character/ddd.js', - 'character/diy.js', 'character/extra.js', - 'character/gujian.js', - 'character/gwent.js', - 'character/hearth.js', 'character/huicui.js', - 'character/jiange.js', 'character/jsrg.js', 'character/mobile.js', - 'character/mtg.js', 'character/offline.js', - 'character/old.js', - 'character/onlyOL.js', - 'character/ow.js', 'character/rank.js', 'character/refresh.js', 'character/sb.js', 'character/shenhua.js', - 'character/shiji.js', 'character/sp.js', 'character/sp2.js', 'character/standard.js', - 'character/swd.js', 'character/tw.js', - 'character/xiake.js', 'character/xianding.js', - 'character/xianjian.js', - 'character/xinghuoliaoyuan.js', - 'character/yijiang.js', - 'character/yingbian.js', - 'character/yxs.js', - - 'extension/boss/extension.js', - 'game/codemirror.js', - 'game/config.js', - 'game/core-js-bundle.js', - 'game/entry.js', 'game/game.js', - 'game/package.js', 'game/source.js', 'mode/boss.js', - 'mode/brawl.js', - 'mode/chess.js', - 'mode/doudizhu.js', - 'mode/guozhan.js', - 'mode/identity.js', - 'mode/realtime.js', - 'mode/single.js', - 'mode/stone.js', - 'mode/tafang.js', - 'mode/versus.js', 'noname.js', - 'noname/ai/basic.js', - 'noname/ai/index.js', 'noname/game/index.js', - 'noname/game/promises.js', - 'noname/game/dynamic-style/index.js', + 'noname/get/index.js', 'noname/get/is.js', - 'noname/gnc/index.js', - 'noname/gnc/is.js', + 'noname/init/cordova.js', 'noname/init/import.js', 'noname/init/index.js', - 'noname/init/node.js', - 'noname/init/onload.js', - 'noname/init/polyfill.js', + 'noname/library/index.js', - 'noname/library/path.js', - 'noname/library/announce/index.d.ts', - 'noname/library/announce/index.js', - 'noname/library/channel/index.js', - 'noname/library/element/button.js', - 'noname/library/element/card.js', - 'noname/library/element/client.js', + 'noname/library/element/content.js', - 'noname/library/element/contents.js', - 'noname/library/element/control.js', - 'noname/library/element/dialog.js', 'noname/library/element/gameEvent.js', 'noname/library/element/gameEventPromise.js', - 'noname/library/element/index.js', - 'noname/library/element/nodeWS.js', - 'noname/library/element/player.js', 'noname/library/element/vcard.js', - 'noname/library/experimental/index.js', - 'noname/library/experimental/symbol.js', - 'noname/library/init/index.js', - 'noname/library/init/promises.js', - 'noname/status/index.js', + 'noname/ui/index.js', - 'noname/util/browser.js', - 'noname/util/config.js', - 'noname/util/index.js', - 'noname/util/mutex.js', - 'noname/util/struct/index.js', - 'noname/util/struct/interface/index.d.ts', - 'noname/util/struct/interface/promise-error-handler.d.ts', + 'noname/util/struct/promise-error-handler/chrome.js', - 'noname/util/struct/promise-error-handler/firefox.js', - 'noname/util/struct/promise-error-handler/index.js', 'noname/util/struct/promise-error-handler/unknown.js', ] }; diff --git a/image/character/liyi.jpg b/image/character/liyi.jpg new file mode 100644 index 000000000..f099a78b5 Binary files /dev/null and b/image/character/liyi.jpg differ diff --git a/index.html b/index.html index abe49f125..6ec89d172 100755 --- a/index.html +++ b/index.html @@ -18,118 +18,130 @@ diff --git a/mode/guozhan.js b/mode/guozhan.js index e723cc048..9f782e05a 100644 --- a/mode/guozhan.js +++ b/mode/guozhan.js @@ -10144,10 +10144,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ target:function(card,player,target){ if(player.hasSkillTag('jueqing',false,target)) return; if(player==target.getNext()||player==target.getPrevious()) return; - var num=get.tag(card,'damage'); - if(num){ - return 0; - } + if(get.tag(card,'damage')) return 'zeroplayertarget'; }, }, }, @@ -10578,7 +10575,10 @@ game.import('mode',function(lib,game,ui,get,ai,_status){ player:function(player,target){ var huoshao=false; for(var i=0;i; bannedKeyWords: string[]; } diff --git a/noname/game/index.js b/noname/game/index.js index 39e03eaf5..77b4bcdbc 100644 --- a/noname/game/index.js +++ b/noname/game/index.js @@ -8434,6 +8434,21 @@ export class Game extends Uninstantable { return true; }); } -}; + /** + * 此方法用于对所有targets按顺序执行一个async函数。 + * + * @param { Player[] } targets 需要执行async方法的目标 + * @param { AsyncFunction } asyncFunc 需要执行的async方法 + * @param { sort } function 排序器,默认为lib.sort.seat + */ + static async doAsyncInOrder(targets,asyncFunc,sort){ + if(!sort)sort = lib.sort.seat; + let sortedTargets = targets.sort(sort); + for(let i=0;i 其他后续或许会增加,但`IE`永无可能 - * + * * @returns {["firefox" | "chrome" | "safari" | "other", number]} */ static coreInfo() { @@ -79,7 +79,7 @@ export class Get extends Uninstantable { } /** * Generate an object URL from the Base64-encoded octet stream - * + * * 从Base64编码的八位字节流生成对象URL */ static objectURL(octetStream) { @@ -91,7 +91,7 @@ export class Get extends Uninstantable { } /** * Get the card name length - * + * * 获取此牌的字数 */ static cardNameLength(card, player) { @@ -102,7 +102,7 @@ export class Get extends Uninstantable { //应变 /** * Get the Yingbian conditions (of the card) - * + * * 获取(此牌的)应变条件 */ static yingbianConditions(card) { return get.complexYingbianConditions(card).concat(get.simpleYingbianConditions(card)); } @@ -116,7 +116,7 @@ export class Get extends Uninstantable { } /** * Get the Yingbian effects (of the card) - * + * * 获取(此牌的)应变效果 */ static yingbianEffects(card) { @@ -125,7 +125,7 @@ export class Get extends Uninstantable { } /** * Get the default Yingbian effect of the card - * + * * 获取此牌的默认应变效果 */ static defaultYingbianEffect(card) { @@ -154,9 +154,9 @@ export class Get extends Uninstantable { } /** * 新装备栏相关 - * + * * 获取一张装备牌实际占用的装备栏(君曹操六龙) - * + * * 用法同get.subtype,返回数组 */ static subtypes(obj, player) { @@ -506,14 +506,14 @@ export class Get extends Uninstantable { } /** * @overload - * @param { string } name + * @param { string } name * @returns { Character } */ /** * @template { 0 | 1 | 2 | 3 | 4 } T * @overload - * @param { string } name - * @param { T } num + * @param { string } name + * @param { T } num * @returns { Character[T] } */ static character(name, num) { @@ -794,9 +794,9 @@ export class Get extends Uninstantable { } /** * 深拷贝函数(虽然只处理了部分情况) - * + * * 除了普通的Object和NullObject,均不考虑自行赋值的数据,但会原样将Symbol复制过去 - * + * * @template T * @param {T} obj - 要复制的对象,若不是对象则直接返回原值 * @param {boolean} [copyKeyDeep = false] - 是否深复制`Map`的`key` @@ -1586,52 +1586,52 @@ export class Get extends Uninstantable { */ /** * @overload - * @param { string } obj + * @param { string } obj * @returns { 'position' | 'natures' | 'nature' } */ /** * @overload - * @param { Player[] } obj + * @param { Player[] } obj * @returns { 'players' } */ /** * @overload - * @param { Card[] } obj + * @param { Card[] } obj * @returns { 'cards' } */ /** * @overload - * @param { [number, number] } obj + * @param { [number, number] } obj * @returns { 'select' } */ /** * @overload - * @param { [number, number, number, number] } obj + * @param { [number, number, number, number] } obj * @returns { 'divposition' } */ /** * @overload - * @param { Button } obj + * @param { Button } obj * @returns { 'button' } */ /** * @overload - * @param { Card } obj + * @param { Card } obj * @returns { 'card' } */ /** * @overload - * @param { Player } obj + * @param { Player } obj * @returns { 'player' } */ /** * @overload - * @param { Dialog } obj + * @param { Dialog } obj * @returns { 'dialog' } */ /** * @overload - * @param { GameEvent | GameEventPromise } obj + * @param { GameEvent | GameEventPromise } obj * @returns { 'event' } */ static itemtype(obj) { @@ -1716,7 +1716,7 @@ export class Get extends Uninstantable { return 0; } /** - * + * * @param {Card | VCard} card * @param {false | Player} [player] * @returns {string} @@ -1736,7 +1736,7 @@ export class Get extends Uninstantable { * @returns {string} */ static suit(card, player) { - if (!card) return; + if (typeof card !== 'object') return; if (Array.isArray(card)) { if (card.length == 1) return get.suit(card[0], player); return 'none'; @@ -1761,7 +1761,7 @@ export class Get extends Uninstantable { * @returns {string} */ static color(card, player) { - if (!card) return; + if (typeof card !== 'object') return; if (Array.isArray(card)) { if (!card.length) return 'none'; const cards = card.slice(), color = get.color(cards.shift(), player); @@ -1790,7 +1790,7 @@ export class Get extends Uninstantable { * @returns {number} */ static number(card, player) { - if (!card) return; + if (typeof card !== 'object') return; //狗卡你是真敢出啊 var number = null; if ('number' in card) { diff --git a/noname/init/index.js b/noname/init/index.js index 02835a5f8..0a37ea546 100644 --- a/noname/init/index.js +++ b/noname/init/index.js @@ -106,7 +106,7 @@ export async function boot() { else if (!Reflect.has(lib, 'device')) { Reflect.set(lib, 'path', (await import('../library/path.js')).default); //为其他自定义平台提供文件读写函数赋值的一种方式。 - //但这种方式只能修改game的文件读写函数。 + //但这种方式只允许修改game的文件读写函数。 if (typeof window.initReadWriteFunction == 'function') { const g = {}; const ReadWriteFunctionName = ['download', 'readFile', 'readFileAsText', 'writeFile', 'removeFile', 'getFileList', 'ensureDirectory', 'createDir']; @@ -123,7 +123,9 @@ export async function boot() { }); }); // @ts-ignore - window.initReadWriteFunction(g); + await window.initReadWriteFunction(g).catch(e => { + console.error('文件读写函数初始化失败:', e); + }); } window.onbeforeunload = function () { if (config.get('confirm_exit') && !_status.reloading) { @@ -862,7 +864,13 @@ async function setOnError() { } //解析parsex里的content fun内容(通常是技能content) // @ts-ignore - else if (err && err.stack && ['at Object.eval [as content]', 'at Proxy.content'].some(str => err.stack.split('\n')[1].trim().startsWith(str))) { + else if (err && err.stack && ['at Object.eval [as content]', 'at Proxy.content'].some(str =>{ + let stackSplit1 = err.stack.split('\n')[1]; + if(stackSplit1){ + return stackSplit1.trim().startsWith(str); + } + return false; + })) { const codes = _status.event.content; if (typeof codes == 'function') { const lines = codes.toString().split("\n"); diff --git a/noname/library/element/content.js b/noname/library/element/content.js index 3e97d22a0..b141b113b 100644 --- a/noname/library/element/content.js +++ b/noname/library/element/content.js @@ -2011,8 +2011,10 @@ export const Content = { } }, arrangeTrigger: async function (event,trigger,player) { - while(event.doingList.length>0){ - event.doing = event.doingList.shift(); + const doingList = event.doingList.slice(0); + + while(doingList.length>0){ + event.doing = doingList.shift(); while(true){ if (trigger.filterStop && trigger.filterStop()) return; const usableSkills = event.doing.todoList.filter(info => { @@ -2030,10 +2032,10 @@ export const Content = { } else { event.choice = usableSkills.filter(n => n.priority == usableSkills[0].priority); - //现在只要找到一个同优先度技能为silent 便优先执行该技能 + //现在只要找到一个同优先度技能为silent,或没有技能描述的技能 便优先执行该技能 const silentSkill = event.choice.find(item => { const skillInfo = lib.skill[item.skill]; - return (skillInfo && skillInfo.silent); + return (skillInfo && (skillInfo.silent || !lib.translate[item.skill])); }) if (silentSkill){ event.current = silentSkill; diff --git a/noname/library/element/gameEventPromise.js b/noname/library/element/gameEventPromise.js index 3b650cf5c..9db3808f0 100644 --- a/noname/library/element/gameEventPromise.js +++ b/noname/library/element/gameEventPromise.js @@ -1,9 +1,7 @@ -import { AI as ai } from '../../ai/index.js'; import { Get as get } from '../../get/index.js'; import { Game as game } from '../../game/index.js'; import { Library as lib } from "../index.js"; import { status as _status } from '../../status/index.js'; -import { UI as ui } from '../../ui/index.js'; import { AsyncFunction } from '../../util/index.js'; /** @@ -16,7 +14,7 @@ import { AsyncFunction } from '../../util/index.js'; * 且Promise的原有属性无法被修改,一切对这个类实例的属性修改,删除, * 再配置等操作都会转发到事件对应的属性中。 * - * @template { GameEvent } T + * @extends {Promise} * * @example * 使用await xx()等待异步事件执行: diff --git a/noname/library/element/player.js b/noname/library/element/player.js index 139e8d356..f4e6a20ef 100644 --- a/noname/library/element/player.js +++ b/noname/library/element/player.js @@ -203,6 +203,22 @@ export class Player extends HTMLDivElement { handcards2: ui.create.div('.handcards'), expansions: ui.create.div('.expansions') }; + if(lib.config.equip_span){ + let observer = new MutationObserver(mutationsList=>{ + for (let mutation of mutationsList) { + if (mutation.type === 'childList') { + const addedNodes = Array.from(mutation.addedNodes); + const removedNodes = Array.from(mutation.removedNodes); + if(addedNodes.some(card=>!card.classList.contains('emptyequip')) || + removedNodes.some(card=>!card.classList.contains('emptyequip'))){ + player.$handleEquipChange(); + } + } + } + }); + const config = { childList: true }; + observer.observe(node.equips, config); + } node.expansions.style.display = 'none'; const chainLength = game.layout == 'default' ? 64 : 40; for (let repetition = 0; repetition < chainLength; repetition++) { @@ -2896,14 +2912,14 @@ export class Player extends HTMLDivElement { } else if (arg1[i] == 'e') { for (j = 0; j < this.node.equips.childElementCount; j++) { - if (!this.node.equips.childNodes[j].classList.contains('removing') && !this.node.equips.childNodes[j].classList.contains('feichu')) { + if (!this.node.equips.childNodes[j].classList.contains('removing') && !this.node.equips.childNodes[j].classList.contains('feichu') && !this.node.equips.childNodes[j].classList.contains('emptyequip')) { cards.push(this.node.equips.childNodes[j]); } } } else if (arg1[i] == 'j') { for (j = 0; j < this.node.judges.childElementCount; j++) { - if (!this.node.judges.childNodes[j].classList.contains('removing') && !this.node.judges.childNodes[j].classList.contains('feichu')) { + if (!this.node.judges.childNodes[j].classList.contains('removing') && !this.node.judges.childNodes[j].classList.contains('feichu') && !this.node.judges.childNodes[j].classList.contains('emptyequip')) { cards.push(this.node.judges.childNodes[j]); if (this.node.judges.childNodes[j].viewAs && arguments.length > 1) { this.node.judges.childNodes[j].tempJudge = this.node.judges.childNodes[j].name; @@ -3074,7 +3090,7 @@ export class Player extends HTMLDivElement { var es = []; if (arg3 !== false) { for (i = 0; i < this.node.equips.childElementCount; i++) { - if (!this.node.equips.childNodes[i].classList.contains('removing') && !this.node.equips.childNodes[i].classList.contains('feichu')) { + if (!this.node.equips.childNodes[i].classList.contains('removing') && !this.node.equips.childNodes[i].classList.contains('feichu') && !this.node.equips.childNodes[i].classList.contains('emptyequip')) { var equipskills = get.info(this.node.equips.childNodes[i]).skills; if (equipskills) { es.addArray(equipskills); @@ -3115,19 +3131,19 @@ export class Player extends HTMLDivElement { for (i = 0; i < arg1.length; i++) { if (arg1[i] == 'h') { for (j = 0; j < this.node.handcards1.childElementCount; j++) { - if (!this.node.handcards1.childNodes[j].classList.contains('removing') && !this.node.handcards1.childNodes[j].classList.contains('feichu') && !this.node.handcards1.childNodes[j].classList.contains('glows')) { + if (!this.node.handcards1.childNodes[j].classList.contains('removing') && !this.node.handcards1.childNodes[j].classList.contains('feichu') && !this.node.handcards1.childNodes[j].classList.contains('emptyequip') && !this.node.handcards1.childNodes[j].classList.contains('glows')) { cards.push(this.node.handcards1.childNodes[j]); } } for (j = 0; j < this.node.handcards2.childElementCount; j++) { - if (!this.node.handcards2.childNodes[j].classList.contains('removing') && !this.node.handcards2.childNodes[j].classList.contains('feichu') && !this.node.handcards2.childNodes[j].classList.contains('glows')) { + if (!this.node.handcards2.childNodes[j].classList.contains('removing') && !this.node.handcards2.childNodes[j].classList.contains('feichu') && !this.node.handcards2.childNodes[j].classList.contains('emptyequip') && !this.node.handcards2.childNodes[j].classList.contains('glows')) { cards.push(this.node.handcards2.childNodes[j]); } } } else if (arg1[i] == 'e') { for (j = 0; j < this.node.equips.childElementCount; j++) { - if (!this.node.equips.childNodes[j].classList.contains('removing') && !this.node.equips.childNodes[j].classList.contains('feichu')) { + if (!this.node.equips.childNodes[j].classList.contains('removing') && !this.node.equips.childNodes[j].classList.contains('feichu') && !this.node.equips.childNodes[j].classList.contains('emptyequip')) { cards.push(this.node.equips.childNodes[j]); } } @@ -3140,7 +3156,7 @@ export class Player extends HTMLDivElement { } else if (arg1[i] == 'j') { for (j = 0; j < this.node.judges.childElementCount; j++) { - if (!this.node.judges.childNodes[j].classList.contains('removing') && !this.node.judges.childNodes[j].classList.contains('feichu')) { + if (!this.node.judges.childNodes[j].classList.contains('removing') && !this.node.judges.childNodes[j].classList.contains('feichu') && !this.node.judges.childNodes[j].classList.contains('emptyequip')) { cards.push(this.node.judges.childNodes[j]); if (this.node.judges.childNodes[j].viewAs && arguments.length > 1) { this.node.judges.childNodes[j].tempJudge = this.node.judges.childNodes[j].name; @@ -9090,6 +9106,66 @@ export class Player extends HTMLDivElement { } } } + $handleEquipChange(){ + let player = this; + const cards = Array.from(this.node.equips.childNodes); + const cardsResume = cards.slice(0); + cards.forEach(card=>{ + if(card.name.indexOf('empty_equip') == 0){ + let num = get.equipNum(card); + let remove = false; + if((num == 4 || num == 3) && get.is.mountCombined()){ + remove = !this.hasEmptySlot('equip3_4') || this.getEquips('equip3_4').length; + }else if(!this.hasEmptySlot(num) || this.getEquips(num).length){ + remove = true; + } + if(remove){ + this.node.equips.removeChild(card); + cardsResume.remove(card); + } + } + }); + for(let i=1;i<=4;i++){ + let add = false; + if((i == 4 || i == 3) && get.is.mountCombined()){ + add = this.hasEmptySlot('equip3_4') && !this.getEquips('equip3_4').length; + }else{ + add = this.hasEmptySlot(i) && !this.getEquips(i).length; + } + if(add && !cardsResume.some(card=>{ + let num = get.equipNum(card); + if((i==4|| i==3) && get.is.mountCombined()){ + return num == 4 || num == 3; + }else{ + return num == i; + } + })){ + const card = game.createCard('empty_equip' + i,'', ''); + card.fix(); + console.log('add '+card.name); + card.style.transform = ''; + card.classList.remove('drawinghidden'); + card.classList.add('emptyequip'); + card.classList.add('hidden'); + delete card._transform; + const equipNum = get.equipNum(card); + let equipped = false; + for (let j = 0; j < player.node.equips.childNodes.length; j++) { + if (get.equipNum(player.node.equips.childNodes[j]) >= equipNum) { + player.node.equips.insertBefore(card, player.node.equips.childNodes[j]); + equipped = true; + break; + } + } + if (!equipped) { + player.node.equips.appendChild(card); + if (_status.discarded) { + _status.discarded.remove(card); + } + } + } + } + } $equip(card) { game.broadcast(function (player, card) { player.$equip(card); diff --git a/noname/library/index.js b/noname/library/index.js index 2c63d5759..de78ae4b6 100644 --- a/noname/library/index.js +++ b/noname/library/index.js @@ -5,7 +5,7 @@ * @typedef { InstanceType } Button * @typedef { InstanceType } Dialog * @typedef { InstanceType } GameEvent - * @typedef { InstanceType & InstanceType> } GameEventPromise + * @typedef { InstanceType & InstanceType } GameEventPromise * @typedef { InstanceType } NodeWS * @typedef { InstanceType } Control */ @@ -3056,6 +3056,12 @@ export class Library extends Uninstantable { lib.init.cssstyles(); } }, + equip_span:{ + name: '装备牌占位', + intro:'打开后,没有装备的装备区将在装备栏占据空白位置。', + init: false, + unfrequent:false, + }, fold_card: { name: '折叠手牌', init: true, @@ -9577,6 +9583,30 @@ export class Library extends Uninstantable { type: "equip", subtype: "equip6", }, + empty_equip1: { + type: "equip", + subtype: "equip1", + }, + empty_equip2: { + type: "equip", + subtype: "equip2", + }, + empty_equip3: { + type: "equip", + subtype: "equip3", + }, + empty_equip4: { + type: "equip", + subtype: "equip4", + }, + empty_equip5: { + type: "equip", + subtype: "equip5", + }, + empty_equip6: { + type: "equip", + subtype: "equip6", + }, zhengsu_leijin: {}, zhengsu_mingzhi: {}, zhengsu_bianzhen: {}, @@ -11228,6 +11258,7 @@ export class Library extends Uninstantable { charlotte: true, priority: -100, lastDo: true, + silent:true, content: function () { player.removeSkill('counttrigger'); delete player.storage.counttrigger; @@ -11253,6 +11284,7 @@ export class Library extends Uninstantable { priority: 100, firstDo: true, popup: false, + silent:true, filter: function (event, player) { return player.hp >= player.maxHp; }, @@ -11341,6 +11373,7 @@ export class Library extends Uninstantable { popup: false, priority: -100, lastDo: true, + silent:true, filter: function (event) { return !event._cleared && event.card.name != 'wuxie'; }, @@ -11357,6 +11390,7 @@ export class Library extends Uninstantable { popup: false, priority: -100, lastDo: true, + silent:true, filter: function (event) { return ui.todiscard[event.discardid] ? true : false; }, @@ -11386,6 +11420,7 @@ export class Library extends Uninstantable { priority: 5, forced: true, popup: false, + silent:true, filter: function (event, player) { //if(!event.player.isDying()) return false; //if(event.source&&event.source.isIn()&&event.source!=player) return false; @@ -11539,6 +11574,7 @@ export class Library extends Uninstantable { popup: false, logv: false, forceDie: true, + silent:true, //priority:-5, content: function () { "step 0"; @@ -11567,6 +11603,7 @@ export class Library extends Uninstantable { forced: true, popup: false, forceDie: true, + silent:true, filter: function (event, player) { var evt = event.getParent(); return evt && evt.name == 'damage' && evt.hasNature('linked') && player.isLinked(); @@ -13088,7 +13125,7 @@ export class Library extends Uninstantable { static other = { ignore: () => void 0 }; -}; +} Library.config = undefined; Library.configOL = undefined; diff --git a/noname/util/struct/promise-error-handler/chrome.js b/noname/util/struct/promise-error-handler/chrome.js index a5120a367..e76317535 100644 --- a/noname/util/struct/promise-error-handler/chrome.js +++ b/noname/util/struct/promise-error-handler/chrome.js @@ -129,12 +129,16 @@ export class ChromePromiseErrorHandler { } // 反之我们只能不考虑报错文件信息,直接调用onerror else { - // @ts-ignore - let [_, src = void 0, line = void 0, column = void 0] = /at\s+.*\s+\((.*):(\d*):(\d*)\)/i.exec(error.stack.split('\n')[1]) - if (typeof line == 'string') line = Number(line); - if (typeof column == 'string') column = Number(column); - // @ts-ignore - window.onerror(error.message, src, line, column, error); + try{ + // @ts-ignore + let [_, src = void 0, line = void 0, column = void 0] = /at\s+.*\s+\((.*):(\d*):(\d*)\)/i.exec(error.stack.split('\n')[1]) + if (typeof line == 'string') line = Number(line); + if (typeof column == 'string') column = Number(column); + // @ts-ignore + window.onerror(error.message, src, line, column, error); + }catch(e){ + window.onerror(error.message,'',0,0, error); + } } } /*