|
@ -184,8 +184,8 @@ game.import('card',function(lib,game,ui,get,ai,_status){
|
||||||
}
|
}
|
||||||
"step 3"
|
"step 3"
|
||||||
if((!result||!result.bool||!result.result||result.result!='shaned')&&!event.unhurt){
|
if((!result||!result.bool||!result.result||result.result!='shaned')&&!event.unhurt){
|
||||||
if (!event.directHit&&!event.directHit2&&lib.filter.cardEnabled(new lib.element.VCard('shan'), target, 'forceEnable')&&
|
if (!event.directHit&&!event.directHit2&&lib.filter.cardEnabled(new lib.element.VCard({name:'shan'}), target, 'forceEnable')&&
|
||||||
target.hasCard(()=>true,'hs')&&get.damageEffect(target,player,target)<0) target.addGaintag(target.getCards('hs'),'sha_notshan');
|
target.countCards('hs')>0&&get.damageEffect(target,player,target)<0) target.addGaintag(target.getCards('hs'),'sha_notshan');
|
||||||
target.damage(get.nature(event.card));
|
target.damage(get.nature(event.card));
|
||||||
event.result={bool:true}
|
event.result={bool:true}
|
||||||
event.trigger('shaDamage');
|
event.trigger('shaDamage');
|
||||||
|
|
|
@ -411,7 +411,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){
|
||||||
equipSkill:true,
|
equipSkill:true,
|
||||||
forced:true,
|
forced:true,
|
||||||
trigger:{target:'gift'},
|
trigger:{target:'gift'},
|
||||||
filter:(event,player)=>event.target!=player,
|
filter:(event,player)=>event.player!=player,
|
||||||
logTarget:'player',
|
logTarget:'player',
|
||||||
content:()=>{
|
content:()=>{
|
||||||
trigger.deniedGift.add(trigger.card);
|
trigger.deniedGift.add(trigger.card);
|
||||||
|
|
|
@ -155,8 +155,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
'虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。',
|
'虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。',
|
||||||
'鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。',
|
'鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。',
|
||||||
'熊:每回合限一次,当你受到伤害时,此伤害-1。',
|
'熊:每回合限一次,当你受到伤害时,此伤害-1。',
|
||||||
'猿:出牌阶段开始时,你选择一名角色,随机获得其装备区里的一张牌。',
|
'猿:当你获得此效果时,你选择一名其他角色,获得其装备区里的一张牌。',
|
||||||
'鹤:出牌阶段开始时,你摸三张牌。',
|
'鹤:当你获得此效果时,你摸三张牌。',
|
||||||
],
|
],
|
||||||
updateMark:function(player){
|
updateMark:function(player){
|
||||||
var wuqinxi=player.storage.wuling_wuqinxi;
|
var wuqinxi=player.storage.wuling_wuqinxi;
|
||||||
|
@ -177,11 +177,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
game.broadcastAll(function(player,curMark){
|
game.broadcastAll(function(player,curMark){
|
||||||
if(player.marks.wuling_wuqinxi) player.marks.wuling_wuqinxi.firstChild.innerHTML=curMark;
|
if(player.marks.wuling_wuqinxi) player.marks.wuling_wuqinxi.firstChild.innerHTML=curMark;
|
||||||
},player,curMark);
|
},player,curMark);
|
||||||
if(curMark=='鹿'){
|
var next=game.createEvent('wuling_change');
|
||||||
player.logSkill('wuling_wuqinxi');
|
next.player=player;
|
||||||
player.recover();
|
next.setContent('emptyEvent');
|
||||||
player.discard(player.getCards('j')).discarder=player;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
ai:{
|
ai:{
|
||||||
order:7,
|
order:7,
|
||||||
|
@ -214,7 +212,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
},
|
},
|
||||||
trigger:{
|
trigger:{
|
||||||
source:'damageBegin1',
|
source:'damageBegin1',
|
||||||
player:['phaseZhunbeiBegin','damageBegin4','phaseUseBegin'],
|
player:['phaseZhunbeiBegin','damageBegin4','wuling_change'],
|
||||||
},
|
},
|
||||||
filter:function(event,player,name){
|
filter:function(event,player,name){
|
||||||
const wuqinxi=player.storage.wuling_wuqinxi&&player.storage.wuling_wuqinxi[0];
|
const wuqinxi=player.storage.wuling_wuqinxi&&player.storage.wuling_wuqinxi[0];
|
||||||
|
@ -228,9 +226,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
case 'damageBegin4':
|
case 'damageBegin4':
|
||||||
return wuqinxi=='熊'&&!player.hasSkill('wuling_xiong');
|
return wuqinxi=='熊'&&!player.hasSkill('wuling_xiong');
|
||||||
default:
|
default:
|
||||||
if(wuqinxi=='鹤') return true;
|
switch(wuqinxi){
|
||||||
if(wuqinxi!='猿') return false;
|
case '鹿':
|
||||||
return game.hasPlayer(target=>target.countGainableCards(player,'e'));
|
return player.isDamaged()||player.countCards('j');
|
||||||
|
case '鹤':
|
||||||
|
return true;
|
||||||
|
case '猿':
|
||||||
|
return game.hasPlayer(target=>target!=playertarget.countGainableCards(player,'e'));
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
forced:true,
|
forced:true,
|
||||||
|
@ -256,31 +262,38 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
event.finish();
|
event.finish();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(wuqinxi=='鹤'){
|
switch(wuqinxi){
|
||||||
player.draw(3);
|
case '鹿':
|
||||||
event.finish();
|
player.recover();
|
||||||
}
|
player.discard(player.getCards('j')).discarder=player;
|
||||||
else{
|
event.finish();
|
||||||
player.chooseTarget('五禽戏:获得一名角色装备区里的一张装备牌',function(card,player,target){
|
break;
|
||||||
return target.countGainableCards(player,'e');
|
case '鹤':
|
||||||
}).set('ai',function(target){
|
player.draw(3);
|
||||||
var player=_status.event.player;
|
event.finish();
|
||||||
var att=get.attitude(player,target),eff=0;
|
break;
|
||||||
target.getCards('e',function(card){
|
case '猿':
|
||||||
var val=get.value(card,target);
|
player.chooseTarget('五禽戏:获得一名其他角色装备区里的一张装备牌',function(card,player,target){
|
||||||
eff=Math.max(eff,-val*att);
|
return target!=player&&target.countGainableCards(player,'e');
|
||||||
|
}).set('ai',function(target){
|
||||||
|
var player=_status.event.player;
|
||||||
|
var att=get.attitude(player,target),eff=0;
|
||||||
|
target.getCards('e',function(card){
|
||||||
|
var val=get.value(card,target);
|
||||||
|
eff=Math.max(eff,-val*att);
|
||||||
|
});
|
||||||
|
return eff;
|
||||||
});
|
});
|
||||||
return eff;
|
break;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'step 1'
|
'step 1'
|
||||||
if(result.bool){
|
if(result.bool){
|
||||||
var target=result.targets[0];
|
var target=result.targets[0];
|
||||||
player.line(target,'green');
|
player.line(target,'green');
|
||||||
var cards=target.getGainableCards(player,'e');
|
player.gainPlayerCard(target,'e',true);
|
||||||
player.gain(cards.randomGets(1),target,'give');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ai:{
|
ai:{
|
||||||
|
@ -7014,11 +7027,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
source:'damageSource'
|
source:'damageSource'
|
||||||
},
|
},
|
||||||
filter:function(event,player){
|
filter:function(event,player){
|
||||||
if(get.attitude(_status.event.player,event.player)>=0) return false;
|
|
||||||
if(player.storage.drlt_duorui.length) return false;
|
if(player.storage.drlt_duorui.length) return false;
|
||||||
return event.player.isIn()&&_status.currentPhase==player;
|
return event.player.isIn()&&_status.currentPhase==player;
|
||||||
},
|
},
|
||||||
check:function(event,player){
|
check:function(event,player){
|
||||||
|
if(get.attitude(_status.event.player,event.player)>=0) return false;
|
||||||
if(player.hasEnabledSlot()&&!player.hasEnabledSlot(5)) return false;
|
if(player.hasEnabledSlot()&&!player.hasEnabledSlot(5)) return false;
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -8049,8 +8062,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
'<br><li>虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。'+
|
'<br><li>虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。'+
|
||||||
'<br><li>鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。'+
|
'<br><li>鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。'+
|
||||||
'<br><li>熊:每回合限一次,当你受到伤害时,此伤害-1。'+
|
'<br><li>熊:每回合限一次,当你受到伤害时,此伤害-1。'+
|
||||||
'<br><li>猿:出牌阶段开始时,你选择一名角色,随机获得其装备区里的一张牌。'+
|
'<br><li>猿:当你获得此效果时,你选择一名其他角色,获得其装备区里的一张牌。'+
|
||||||
'<br><li>鹤:出牌阶段开始时,你摸三张牌。',
|
'<br><li>鹤:当你获得此效果时,你摸三张牌。',
|
||||||
youyi:'游医',
|
youyi:'游医',
|
||||||
youyi_info:'①弃牌阶段结束时,你可以将所有于此阶段弃置的牌置入仁区。②出牌阶段限一次。你可以将仁区的所有牌置入弃牌堆,令所有角色各回复1点体力。',
|
youyi_info:'①弃牌阶段结束时,你可以将所有于此阶段弃置的牌置入仁区。②出牌阶段限一次。你可以将仁区的所有牌置入弃牌堆,令所有角色各回复1点体力。',
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
sp_jishi:['dc_jiben','zhenghun','dc_sunhanhua','liuchongluojun'],
|
sp_jishi:['dc_jiben','zhenghun','dc_sunhanhua','liuchongluojun'],
|
||||||
sp_raoting:['dc_huanghao','dc_sunziliufang','dc_sunchen','dc_jiachong'],
|
sp_raoting:['dc_huanghao','dc_sunziliufang','dc_sunchen','dc_jiachong'],
|
||||||
sp_yijun:['gongsundu','mengyou'],
|
sp_yijun:['gongsundu','mengyou'],
|
||||||
sp_zhengyin:['yue_caiwenji','yue_zhoufei','yue_caiyong'],
|
sp_zhengyin:['yue_caiwenji','yue_zhoufei','yue_caiyong','yue_xiaoqiao'],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
skill:{
|
skill:{
|
||||||
|
@ -658,7 +658,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
trigger:{global:'phaseEnd'},
|
trigger:{global:'phaseEnd'},
|
||||||
forced:true,
|
forced:true,
|
||||||
filter:function(event,player){
|
filter:function(event,player){
|
||||||
return player.getHistory('useCard').length>player.getHp();
|
return player.getHistory('useCard').length>player.getHp()||player.getHistory('gain').reduce((sum,evt)=>sum+evt.cards.length,0)>player.getHp();
|
||||||
},
|
},
|
||||||
content:function*(event,map){
|
content:function*(event,map){
|
||||||
const player=map.player;
|
const player=map.player;
|
||||||
|
@ -1094,9 +1094,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
trigger:{player:['gainAfter','loseAsyncAfter']},
|
trigger:{player:['gainAfter','loseAsyncAfter']},
|
||||||
forced:true,
|
forced:true,
|
||||||
filter:(event,player)=>{
|
filter:(event,player)=>{
|
||||||
// if(player==_status.currentPhase) return false;
|
|
||||||
if(event.getParent('phaseDraw',true)) return false;
|
if(event.getParent('phaseDraw',true)) return false;
|
||||||
const evt=player.getHistory('gain')[0];
|
const evt=player.getHistory('gain',i=>!i.getParent('phaseDraw',true))[0];
|
||||||
if(!evt) return false;
|
if(!evt) return false;
|
||||||
if(event.name=='gain'){
|
if(event.name=='gain'){
|
||||||
if(evt!=event||event.getlx===false) return false;
|
if(evt!=event||event.getlx===false) return false;
|
||||||
|
@ -1109,8 +1108,8 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
},
|
},
|
||||||
content:function(){
|
content:function(){
|
||||||
var hs=player.getCards('h'),cards=trigger.getg(player);
|
var hs=player.getCards('h'),cards=trigger.getg(player);
|
||||||
var card=cards.filter(card=>hs.includes(card)).randomGet();
|
cards=cards.filter(card=>hs.includes(card));
|
||||||
player.addGaintag(card,'dclingkong_tag');
|
player.addGaintag(cards,'dclingkong_tag');
|
||||||
game.delayx();
|
game.delayx();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2254,7 +2253,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
logTarget:'player',
|
logTarget:'player',
|
||||||
content:function(){
|
content:function(){
|
||||||
var num=trigger.player.countMark('dcshengdu');
|
var num=trigger.player.countMark('dcshengdu');
|
||||||
player.draw(num);
|
player.draw(num*trigger.cards.length);
|
||||||
trigger.player.removeMark('dcshengdu',num);
|
trigger.player.removeMark('dcshengdu',num);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -11093,6 +11092,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
zhangchu:['zhangchu','jsrg_zhangchu'],
|
zhangchu:['zhangchu','jsrg_zhangchu'],
|
||||||
xianglang:['xianglang','mb_xianglang'],
|
xianglang:['xianglang','mb_xianglang'],
|
||||||
chengui:['chengui','mb_chengui'],
|
chengui:['chengui','mb_chengui'],
|
||||||
|
liuyong:['liuyong','jsrg_liuyong'],
|
||||||
|
zhangxuan:['zhangxuan','jsrg_zhangxuan'],
|
||||||
|
gaoxiang:['gaoxiang','jsrg_gaoxiang'],
|
||||||
},
|
},
|
||||||
translate:{
|
translate:{
|
||||||
re_panfeng:'潘凤',
|
re_panfeng:'潘凤',
|
||||||
|
@ -11468,7 +11470,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
dcguangshi_info:'锁定技。准备阶段,若所有其他角色均有“信众”,你摸两张牌并失去1点体力。',
|
dcguangshi_info:'锁定技。准备阶段,若所有其他角色均有“信众”,你摸两张牌并失去1点体力。',
|
||||||
dongwan:'董绾',
|
dongwan:'董绾',
|
||||||
dcshengdu:'生妒',
|
dcshengdu:'生妒',
|
||||||
dcshengdu_info:'回合开始时,你可以选择一名其他角色,令其获得1枚“生妒”标记。有“生妒”标记的角色于摸牌阶段得到牌后,你摸X张牌,然后其移去所有“生妒”标记(X为其拥有的“生妒”标记数)。',
|
dcshengdu_info:'回合开始时,你可以选择一名其他角色,令其获得1枚“生妒”标记。有“生妒”标记的角色于摸牌阶段得到牌后,你摸X张牌,然后其移去所有“生妒”标记(X为摸牌数乘以其拥有的“生妒”标记数)。',
|
||||||
dcjieling:'介绫',
|
dcjieling:'介绫',
|
||||||
dcjieling_info:'出牌阶段每种花色限一次,你可以将两张花色不同的手牌当无距离限制且无任何次数限制的【杀】使用。然后若此【杀】:造成了伤害,所有目标角色失去1点体力;未造成伤害,所有目标角色依次获得1枚“生妒”标记。',
|
dcjieling_info:'出牌阶段每种花色限一次,你可以将两张花色不同的手牌当无距离限制且无任何次数限制的【杀】使用。然后若此【杀】:造成了伤害,所有目标角色失去1点体力;未造成伤害,所有目标角色依次获得1枚“生妒”标记。',
|
||||||
yuanyin:'袁胤',
|
yuanyin:'袁胤',
|
||||||
|
@ -11514,7 +11516,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
yue_zhoufei_prefix:'乐',
|
yue_zhoufei_prefix:'乐',
|
||||||
dclingkong:'灵箜',
|
dclingkong:'灵箜',
|
||||||
dclingkong_tag:'箜篌',
|
dclingkong_tag:'箜篌',
|
||||||
dclingkong_info:'锁定技。①游戏开始时,你将所有手牌标记为“箜篌”。②你的“箜篌”牌不计入手牌上限。③当你于一回合内首次于摸牌阶段外得到牌后,系统随机将其中的一张牌标记为“箜篌”。',
|
dclingkong_info:'锁定技。①游戏开始时,你将所有手牌标记为“箜篌”。②你的“箜篌”牌不计入手牌上限。③当你于一回合内首次于摸牌阶段外得到牌后,你将这些牌标记为“箜篌”。',
|
||||||
dcxianshu:'贤淑',
|
dcxianshu:'贤淑',
|
||||||
dcxianshu_info:'出牌阶段,你可以将一张“箜篌”正面向上交给一名其他角色,然后你摸X张牌(X为你与其的体力值之差且至多为5)。若此牌为红色,且该角色的体力值不大于你,则其回复1点体力;若此牌为黑色,且该角色的体力值不小于你,则其失去1点体力。',
|
dcxianshu_info:'出牌阶段,你可以将一张“箜篌”正面向上交给一名其他角色,然后你摸X张牌(X为你与其的体力值之差且至多为5)。若此牌为红色,且该角色的体力值不大于你,则其回复1点体力;若此牌为黑色,且该角色的体力值不小于你,则其失去1点体力。',
|
||||||
dc_zhangmancheng:'张曼成',
|
dc_zhangmancheng:'张曼成',
|
||||||
|
@ -11531,7 +11533,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
dccaisi:'才思',
|
dccaisi:'才思',
|
||||||
dccaisi_info:'当你于回合内/回合外使用基本牌结算结束后,若你本回合以此法得到的牌数小于你的体力上限,你可以从牌堆/弃牌堆随机获得一张非基本牌,然后本回合下次发动此技能获得的牌数+1。',
|
dccaisi_info:'当你于回合内/回合外使用基本牌结算结束后,若你本回合以此法得到的牌数小于你的体力上限,你可以从牌堆/弃牌堆随机获得一张非基本牌,然后本回合下次发动此技能获得的牌数+1。',
|
||||||
dczhuoli:'擢吏',
|
dczhuoli:'擢吏',
|
||||||
dczhuoli_info:'锁定技。一名角色的回合结束时,若你本回合使用的牌数大于体力值,你加1点体力上限(不能超过存活角色数),回复1点体力。',
|
dczhuoli_info:'锁定技。一名角色的回合结束时,若你本回合使用或获得的牌数大于体力值,你加1点体力上限(不能超过存活角色数),回复1点体力。',
|
||||||
yue_caiyong:'乐蔡邕',
|
yue_caiyong:'乐蔡邕',
|
||||||
yue_caiyong_prefix:'乐',
|
yue_caiyong_prefix:'乐',
|
||||||
dcjiaowei:'焦尾',
|
dcjiaowei:'焦尾',
|
||||||
|
@ -11552,9 +11554,10 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
yue_xiaoqiao:'乐小乔',
|
yue_xiaoqiao:'乐小乔',
|
||||||
yue_xiaoqiao_prefix:'乐',
|
yue_xiaoqiao_prefix:'乐',
|
||||||
dcqiqin:'绮琴',
|
dcqiqin:'绮琴',
|
||||||
dcqiqin_info:'锁定技。①游戏开始时,你将所有手牌标记为“乐”。②你的“乐”牌不计入手牌上限。③准备阶段,你获得弃牌堆中所有你标记过的“乐”牌。',
|
dcqiqin_tag:'琴',
|
||||||
|
dcqiqin_info:'锁定技。①游戏开始时,你将所有手牌标记为“琴”。②你的“琴”牌不计入手牌上限。③准备阶段,你获得弃牌堆中所有你标记过的“琴”牌。',
|
||||||
dcweiwan:'媦婉',
|
dcweiwan:'媦婉',
|
||||||
dcweiwan_info:'出牌阶段限一次,你可以弃置一张“乐”并获得一名其他角色区域内花色与此牌不相同的牌各一张,若你获得了:一张牌,其失去1点体力;两张牌,本回合你对其使用牌无距离和次数限制;三张牌,本回合你不能对其使用牌。',
|
dcweiwan_info:'出牌阶段限一次,你可以弃置一张“琴”并随机获得一名其他角色区域内花色与此牌不相同的牌各一张,若你获得了:一张牌,其失去1点体力;两张牌,本回合你对其使用牌无距离和次数限制;三张牌,本回合你不能对其使用牌。',
|
||||||
|
|
||||||
sp_baigei:'无双上将',
|
sp_baigei:'无双上将',
|
||||||
sp_caizijiaren:'才子佳人',
|
sp_caizijiaren:'才子佳人',
|
||||||
|
|
1975
character/jsrg.js
|
@ -15391,7 +15391,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
zhanggong:['zhanggong','re_zhanggong'],
|
zhanggong:['zhanggong','re_zhanggong'],
|
||||||
baosanniang:['xin_baosanniang','re_baosanniang','baosanniang'],
|
baosanniang:['xin_baosanniang','re_baosanniang','baosanniang'],
|
||||||
heqi:['re_heqi','heqi'],
|
heqi:['re_heqi','heqi'],
|
||||||
weiwenzhugezhi:['weiwenzhugezhi','re_weiwenzhugezhi'],
|
weiwenzhugezhi:['weiwenzhugezhi','re_weiwenzhugezhi','jsrg_weiwenzhugezhi'],
|
||||||
xugong:['xugong','re_xugong','jsrg_xugong'],
|
xugong:['xugong','re_xugong','jsrg_xugong'],
|
||||||
liuzan:['re_liuzan','liuzan'],
|
liuzan:['re_liuzan','liuzan'],
|
||||||
sufei:['yj_sufei','sp_sufei','xf_sufei'],
|
sufei:['yj_sufei','sp_sufei','xf_sufei'],
|
||||||
|
|
|
@ -886,25 +886,39 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
},
|
},
|
||||||
pshengwu:{
|
pshengwu:{
|
||||||
audio:'hengwu',
|
audio:'hengwu',
|
||||||
|
mod:{
|
||||||
|
aiOrder:(player,card,num)=>{
|
||||||
|
if(num>0&&get.tag(card,'draw')&&ui.cardPile.childNodes.length+ui.discardPile.childNodes.length<20) return 0;
|
||||||
|
},
|
||||||
|
aiValue:(player,card,num)=>{
|
||||||
|
if(num>0&&card.name==='zhuge') return 20;
|
||||||
|
},
|
||||||
|
aiUseful:(player,card,num)=>{
|
||||||
|
if(num>0&&card.name==='zhuge') return 10;
|
||||||
|
}
|
||||||
|
},
|
||||||
trigger:{player:['useCard','respond']},
|
trigger:{player:['useCard','respond']},
|
||||||
direct:true,
|
direct:true,
|
||||||
|
locked:false,
|
||||||
filter:function(event,player){
|
filter:function(event,player){
|
||||||
return game.hasPlayer(i=>i.countCards('ej',cardx=>get.type(cardx)=='equip'&&get.suit(event.card)==get.suit(cardx)));
|
return game.hasPlayer(i=>i.countCards('ej',cardx=>get.type(cardx)=='equip'&&get.suit(event.card)==get.suit(cardx)));
|
||||||
},
|
},
|
||||||
content:function(){
|
content:function(){
|
||||||
'step 0'
|
'step 0'
|
||||||
var suit=get.suit(trigger.card);
|
var suit=get.suit(trigger.card),extra=game.filterPlayer().map(i=>i.countCards('ej',cardx=>{
|
||||||
var prompt2='弃置任意张'+get.translation(suit)+'手牌,然后摸X张牌(X为你弃置的牌数+'+game.filterPlayer().map(i=>i.countCards('ej',cardx=>get.type(cardx)=='equip'&&get.suit(trigger.card)==get.suit(cardx))).reduce((p,c)=>p+c)+')';
|
return get.type(cardx)=='equip'&&get.suit(trigger.card)==get.suit(cardx);
|
||||||
|
})).reduce((p,c)=>p+c);
|
||||||
|
var prompt2='弃置任意张'+get.translation(suit)+'手牌,然后摸X张牌(X为你弃置的牌数+'+extra+')';
|
||||||
player.chooseToDiscard('h',[1,player.countCards('h',{suit:suit})],{suit:suit}).set('prompt',get.prompt('pshengwu')).set('prompt2',prompt2).set('ai',card=>{
|
player.chooseToDiscard('h',[1,player.countCards('h',{suit:suit})],{suit:suit}).set('prompt',get.prompt('pshengwu')).set('prompt2',prompt2).set('ai',card=>{
|
||||||
var player=_status.event.player;
|
if(_status.event.tie) return 0;
|
||||||
|
let player=_status.event.player;
|
||||||
if(_status.event.goon) return 12-get.value(card);
|
if(_status.event.goon) return 12-get.value(card);
|
||||||
if(player.countCards('h')>50) return 0;
|
|
||||||
if(player==_status.currentPhase){
|
if(player==_status.currentPhase){
|
||||||
if(['shan','caochuan','tao','wuxie'].includes(card.name)) return 8-get.value(card);
|
if(['shan','caochuan','tao','wuxie'].includes(card.name)) return 8-get.value(card);
|
||||||
return 6-get.value(card);
|
return 6-get.value(card);
|
||||||
}
|
}
|
||||||
return 5.5-get.value(card);
|
return 5.5-get.value(card);
|
||||||
}).set('goon',player.countCards('h',{suit:suit})==1).set('logSkill','pshengwu');
|
}).set('goon',player.countCards('h',{suit:suit})==1).set('tie',extra>ui.cardPile.childNodes.length+ui.discardPile.childNodes.length).set('logSkill','pshengwu');
|
||||||
'step 1'
|
'step 1'
|
||||||
if(result.bool){
|
if(result.bool){
|
||||||
var num=result.cards.length;
|
var num=result.cards.length;
|
||||||
|
@ -2649,7 +2663,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
},
|
},
|
||||||
ai:{
|
ai:{
|
||||||
order:function(item,player){
|
order:function(item,player){
|
||||||
var num=player.getStorage('zyquanji').length;
|
var num=player.getExpansions('zyquanji').length;
|
||||||
if(num==1) return 8;
|
if(num==1) return 8;
|
||||||
return 1;
|
return 1;
|
||||||
},
|
},
|
||||||
|
|
|
@ -987,6 +987,7 @@ window.noname_character_rank={
|
||||||
'libai',
|
'libai',
|
||||||
'tw_gongsunfan',
|
'tw_gongsunfan',
|
||||||
'yue_caiwenji',
|
'yue_caiwenji',
|
||||||
|
'yue_xiaoqiao',
|
||||||
'vtb_xiaole',
|
'vtb_xiaole',
|
||||||
'vtb_xiaojiu',
|
'vtb_xiaojiu',
|
||||||
'ol_zhangzhang',
|
'ol_zhangzhang',
|
||||||
|
@ -1817,6 +1818,7 @@ window.noname_character_rank={
|
||||||
'caoxian',
|
'caoxian',
|
||||||
],
|
],
|
||||||
epic:[
|
epic:[
|
||||||
|
'yue_xiaoqiao',
|
||||||
'mb_chengui',
|
'mb_chengui',
|
||||||
'ol_pengyang',
|
'ol_pengyang',
|
||||||
'ol_luyusheng',
|
'ol_luyusheng',
|
||||||
|
|
|
@ -6656,7 +6656,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
},
|
},
|
||||||
ai:{
|
ai:{
|
||||||
order:function(item,player){
|
order:function(item,player){
|
||||||
var num=player.getStorage('gzquanji').length;
|
var num=player.getExpansions('gzquanji').length;
|
||||||
if(num==1) return 8;
|
if(num==1) return 8;
|
||||||
return 1;
|
return 1;
|
||||||
},
|
},
|
||||||
|
|
|
@ -709,7 +709,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
audio:'sbkanpo',
|
audio:'sbkanpo',
|
||||||
trigger:{global:'useCard'},
|
trigger:{global:'useCard'},
|
||||||
filter:function(event,player){
|
filter:function(event,player){
|
||||||
return event.player!=player&&player.getStorage('sbkanpo').includes(event.card.name);
|
return event.player!=player&&player.storage.sbkanpo[1].includes(event.card.name);
|
||||||
},
|
},
|
||||||
prompt2:function(event,player){
|
prompt2:function(event,player){
|
||||||
return '移除'+get.translation(event.card.name)+'的记录,令'+get.translation(event.card)+'无效';
|
return '移除'+get.translation(event.card.name)+'的记录,令'+get.translation(event.card)+'无效';
|
||||||
|
|
|
@ -3667,7 +3667,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
target:function(card,player,target,current){
|
target:function(card,player,target,current){
|
||||||
if(typeof card==='object'&&get.name(card)==='sha'&&target.mayHaveShan(player,'use')) return [0.6,0.75];
|
if(typeof card==='object'&&get.name(card)==='sha'&&target.mayHaveShan(player,'use')) return [0.6,0.75];
|
||||||
if(!target.hasFriend()&&!player.hasUnknown()) return;
|
if(!target.hasFriend()&&!player.hasUnknown()) return;
|
||||||
if(_status.currentPhase==target) return;
|
if(_status.currentPhase==target||get.type(card)==='delay') return;
|
||||||
if(card.name!='shuiyanqijunx'&&get.tag(card,'loseCard')&&target.countCards('he')){
|
if(card.name!='shuiyanqijunx'&&get.tag(card,'loseCard')&&target.countCards('he')){
|
||||||
if(target.hasSkill('ziliang')) return 0.7;
|
if(target.hasSkill('ziliang')) return 0.7;
|
||||||
return [0.5,Math.max(2,target.countCards('h'))];
|
return [0.5,Math.max(2,target.countCards('h'))];
|
||||||
|
@ -7714,7 +7714,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
dongzhuo:['dongzhuo','ol_dongzhuo','re_dongzhuo','sp_dongzhuo','yj_dongzhuo'],
|
dongzhuo:['dongzhuo','ol_dongzhuo','re_dongzhuo','sp_dongzhuo','yj_dongzhuo'],
|
||||||
dengai:['dengai','ol_dengai','re_dengai'],
|
dengai:['dengai','ol_dengai','re_dengai'],
|
||||||
sp_ol_zhanghe:['sp_ol_zhanghe','yj_zhanghe','sp_zhanghe','jsrg_zhanghe'],
|
sp_ol_zhanghe:['sp_ol_zhanghe','yj_zhanghe','sp_zhanghe','jsrg_zhanghe'],
|
||||||
jiangwei:['jiangwei','ol_jiangwei','re_jiangwei','sb_jiangwei'],
|
jiangwei:['jiangwei','ol_jiangwei','re_jiangwei','sb_jiangwei','jsrg_jiangwei'],
|
||||||
liushan:['liushan','ol_liushan','re_liushan'],
|
liushan:['liushan','ol_liushan','re_liushan'],
|
||||||
sunce:['sunce','re_sunce','re_sunben','sb_sunce'],
|
sunce:['sunce','re_sunce','re_sunben','sb_sunce'],
|
||||||
zhangzhang:['zhangzhang','ol_zhangzhang','re_zhangzhang'],
|
zhangzhang:['zhangzhang','ol_zhangzhang','re_zhangzhang'],
|
||||||
|
|
|
@ -727,7 +727,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
var {result:{bool,targets}}=await player.chooseTarget(get.prompt2('olgongjie'),[1,num],lib.filter.notMe).set('ai',target=>get.attitude(_status.event.player,target));
|
var {result:{bool,targets}}=await player.chooseTarget(get.prompt2('olgongjie'),[1,num],lib.filter.notMe).set('ai',target=>get.attitude(_status.event.player,target));
|
||||||
if(!bool) return;
|
if(!bool) return;
|
||||||
targets=targets.sortBySeat();
|
targets=targets.sortBySeat();
|
||||||
player.logSkill('gongjie',targets);
|
player.logSkill('olgongjie',targets);
|
||||||
for(var target of targets){
|
for(var target of targets){
|
||||||
var {result:{bool,cards}}=await target.gainPlayerCard(player,true,'he');
|
var {result:{bool,cards}}=await target.gainPlayerCard(player,true,'he');
|
||||||
if(bool) draws.add(get.suit(cards[0],player));
|
if(bool) draws.add(get.suit(cards[0],player));
|
||||||
|
@ -788,6 +788,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
return player.countCards('he');
|
return player.countCards('he');
|
||||||
},
|
},
|
||||||
direct:true,
|
direct:true,
|
||||||
|
limited:true,
|
||||||
|
skillAnimation:true,
|
||||||
|
animationColor:'water',
|
||||||
async content(event,trigger,player){
|
async content(event,trigger,player){
|
||||||
var target=_status.currentPhase,num=player.countCards('he');
|
var target=_status.currentPhase,num=player.countCards('he');
|
||||||
var {result:{bool,cards}}=await player.chooseToGive(get.prompt2('olxiangzuo',target),[1,num],'he').set('ai',card=>{
|
var {result:{bool,cards}}=await player.chooseToGive(get.prompt2('olxiangzuo',target),[1,num],'he').set('ai',card=>{
|
||||||
|
@ -951,7 +954,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
forced:true,
|
forced:true,
|
||||||
content:function(){
|
content:function(){
|
||||||
'step 0'
|
'step 0'
|
||||||
player.addTempSkill('olsilv'+(trigger.getg?'gain':'lose'));
|
player.addTempSkill('olsilv_'+(trigger.getg?'gain':'lose'));
|
||||||
if(!trigger.visible){
|
if(!trigger.visible){
|
||||||
var cards,name=player.storage.ollianju;
|
var cards,name=player.storage.ollianju;
|
||||||
if(trigger.getg) cards=trigger.getg(player).filter(card=>card.name==name);
|
if(trigger.getg) cards=trigger.getg(player).filter(card=>card.name==name);
|
||||||
|
@ -13357,7 +13360,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
audio:2,
|
audio:2,
|
||||||
direct:true,
|
direct:true,
|
||||||
filter:function(event,player){
|
filter:function(event,player){
|
||||||
return player!=event.player&&!event.player.isDisabledJudge()&&event.player.countCards('he')&&!event.player.countCards('j');
|
return player!=event.player&&!event.player.isDisabledJudge()&&event.player.countCards('he')&&!event.player.countCards('j',{type:'delay'});
|
||||||
},
|
},
|
||||||
content:function(){
|
content:function(){
|
||||||
'step 0'
|
'step 0'
|
||||||
|
@ -26329,7 +26332,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
retuogu:'托孤',
|
retuogu:'托孤',
|
||||||
retuogu_info:'一名角色死亡时,你可以令其选择其武将牌上的一个技能(主公技,限定技,觉醒技,隐匿技、使命技等特殊技能除外),然后你获得其选择的技能并失去上次因〖托孤〗获得的技能。',
|
retuogu_info:'一名角色死亡时,你可以令其选择其武将牌上的一个技能(主公技,限定技,觉醒技,隐匿技、使命技等特殊技能除外),然后你获得其选择的技能并失去上次因〖托孤〗获得的技能。',
|
||||||
shanzhuan:'擅专',
|
shanzhuan:'擅专',
|
||||||
shanzhuan_info:'当你对其他角色造成伤害后,若其判定区没有牌,则你可以将其的一张牌置于其的判定区。若此牌不为延时锦囊牌且此牌为:红色,此牌视为【乐不思蜀】;黑色,此牌视为【兵粮寸断】。回合结束时,若你本回合内未造成伤害,你可摸一张牌。',
|
shanzhuan_info:'①当你对其他角色造成伤害后,若其判定区没有延时类锦囊牌,则你可以将其的一张牌置于其的判定区。若此牌不为延时锦囊牌且此牌为:红色,此牌视为【乐不思蜀】;黑色,此牌视为【兵粮寸断】。②回合结束时,若你本回合内未造成伤害,你可摸一张牌。',
|
||||||
spniluan:'逆乱',
|
spniluan:'逆乱',
|
||||||
spniluan_info:'出牌阶段,你可以将一张黑色牌当做【杀】使用。此【杀】使用结算完成后,若你未因此【杀】造成过伤害,则你令此【杀】不计入使用次数。',
|
spniluan_info:'出牌阶段,你可以将一张黑色牌当做【杀】使用。此【杀】使用结算完成后,若你未因此【杀】造成过伤害,则你令此【杀】不计入使用次数。',
|
||||||
spweiwu:'违忤',
|
spweiwu:'违忤',
|
||||||
|
|
|
@ -451,6 +451,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
trigger:{player:'phaseEnd',global:'die'},
|
trigger:{player:'phaseEnd',global:'die'},
|
||||||
filter:function(event,player){
|
filter:function(event,player){
|
||||||
if(event.name=='phase') return player.hasMark('starpizhi');
|
if(event.name=='phase') return player.hasMark('starpizhi');
|
||||||
|
if(!player.getStorage('starcanxi_wangsheng').includes(event.player.group)&&!player.getStorage('starcanxi_xiangsi').includes(event.player.group)) return false;
|
||||||
var groups=player.getSkills().filter(skill=>skill.indexOf('starcanxi_')==0);
|
var groups=player.getSkills().filter(skill=>skill.indexOf('starcanxi_')==0);
|
||||||
groups=groups.map(group=>group.slice(10));
|
groups=groups.map(group=>group.slice(10));
|
||||||
return groups.includes(event.player.group);
|
return groups.includes(event.player.group);
|
||||||
|
@ -11181,7 +11182,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
starcanxi_cancel:'向死',
|
starcanxi_cancel:'向死',
|
||||||
starcanxi_info:'锁定技。游戏开始时,你获得场上所有角色的势力对应的“玺角”标记,然后选择一个“玺角”对应势力并选择以下一项;一轮开始时,你选择一个“玺角”对应势力并选择以下一项:①妄生:本轮被选择势力角色每回合首次造成的伤害+1且计算与其他角色间的距离-1;②向死:本轮其他被选择势力角色每回合首次回复体力后失去1点体力且每回合对你使用的第一张牌无效。',
|
starcanxi_info:'锁定技。游戏开始时,你获得场上所有角色的势力对应的“玺角”标记,然后选择一个“玺角”对应势力并选择以下一项;一轮开始时,你选择一个“玺角”对应势力并选择以下一项:①妄生:本轮被选择势力角色每回合首次造成的伤害+1且计算与其他角色间的距离-1;②向死:本轮其他被选择势力角色每回合首次回复体力后失去1点体力且每回合对你使用的第一张牌无效。',
|
||||||
starpizhi:'圮秩',
|
starpizhi:'圮秩',
|
||||||
starpizhi_info:'锁定技。①一名角色死亡后,若你拥有该角色对应的“玺角”标记,你失去之并摸X张牌。②结束阶段,你摸X张牌。(X为你本局游戏失去的“玺角”标记数)',
|
starpizhi_info:'锁定技。①一名角色死亡后,若你拥有该角色对应的“玺角”标记且你本轮发动〖向死〗的势力与其相同,你失去之并摸X张牌。②结束阶段,你摸X张牌。(X为你本局游戏失去的“玺角”标记数)',
|
||||||
starzhonggu:'冢骨',
|
starzhonggu:'冢骨',
|
||||||
starzhonggu_info:'主公技,锁定技。摸牌阶段,若游戏轮数大于等于场上的群势力角色数,则你额外摸两张牌,否则你少摸一张牌。',
|
starzhonggu_info:'主公技,锁定技。摸牌阶段,若游戏轮数大于等于场上的群势力角色数,则你额外摸两张牌,否则你少摸一张牌。',
|
||||||
star_dongzhuo:'星董卓',
|
star_dongzhuo:'星董卓',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
'use strict';
|
import { game } from '../noname.js';
|
||||||
game.import('character',function(lib,game,ui,get,ai,_status){
|
game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
return {
|
return {
|
||||||
name:'standard',
|
name:'standard',
|
||||||
|
@ -93,6 +93,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
ganning:['lingtong','xf_sufei'],
|
ganning:['lingtong','xf_sufei'],
|
||||||
guanyu:['zhangfei','liaohua'],
|
guanyu:['zhangfei','liaohua'],
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @type { { [key: string]: Skill } }
|
||||||
|
*/
|
||||||
skill:{
|
skill:{
|
||||||
//标准版甘夫人
|
//标准版甘夫人
|
||||||
stdshushen:{
|
stdshushen:{
|
||||||
|
@ -304,7 +307,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
logTarget:'source',
|
logTarget:'source',
|
||||||
preHidden:true,
|
preHidden:true,
|
||||||
filter(event,player){
|
filter(event,player){
|
||||||
return (event.source&&event.source.countGainableCards(player,event.source!=player?'he':'e')&&event.num>0);
|
return event.source&&event.source.countGainableCards(player,event.source!=player?'he':'e')>0&&event.num>0;
|
||||||
},
|
},
|
||||||
async content(event,trigger,player){
|
async content(event,trigger,player){
|
||||||
player.gainPlayerCard(true,trigger.source,trigger.source!=player?'he':'e');
|
player.gainPlayerCard(true,trigger.source,trigger.source!=player?'he':'e');
|
||||||
|
@ -1761,9 +1764,9 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
},
|
},
|
||||||
async content(event,trigger,player){
|
async content(event,trigger,player){
|
||||||
event.count=trigger.getl(player).es.length;
|
event.count=trigger.getl(player).es.length;
|
||||||
do {
|
while(event.count-->0){
|
||||||
player.draw(2);
|
player.draw(2);
|
||||||
if(!player.hasSkill(event.name)) break;
|
if(!event.count||!player.hasSkill(event.name)) break;
|
||||||
if(!get.is.blocked(event.name,player)){
|
if(!get.is.blocked(event.name,player)){
|
||||||
const chooseBoolEvent=player.chooseBool(get.prompt2('xiaoji')).set('frequentSkill','xiaoji');
|
const chooseBoolEvent=player.chooseBool(get.prompt2('xiaoji')).set('frequentSkill','xiaoji');
|
||||||
chooseBoolEvent.ai=lib.filter.all;
|
chooseBoolEvent.ai=lib.filter.all;
|
||||||
|
@ -1771,7 +1774,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
if(bool) player.logSkill('xiaoji');
|
if(bool) player.logSkill('xiaoji');
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
}while(event.count-->0);
|
}
|
||||||
},
|
},
|
||||||
ai:{
|
ai:{
|
||||||
noe:true,
|
noe:true,
|
||||||
|
@ -2325,7 +2328,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
characterReplace:{
|
characterReplace:{
|
||||||
caocao:['caocao','re_caocao','sb_caocao','dc_caocao'],
|
caocao:['caocao','re_caocao','sb_caocao','dc_caocao'],
|
||||||
guojia:['guojia','re_guojia','ps1059_guojia','ps2070_guojia'],
|
guojia:['guojia','re_guojia','ps1059_guojia','ps2070_guojia'],
|
||||||
simayi:['simayi','re_simayi','ps_simayi','ps2068_simayi'],
|
simayi:['simayi','re_simayi','jsrg_simayi','ps_simayi','ps2068_simayi'],
|
||||||
jin_simayi:['jin_simayi','junk_simayi','ps_jin_simayi'],
|
jin_simayi:['jin_simayi','junk_simayi','ps_jin_simayi'],
|
||||||
zhenji:['zhenji','re_zhenji','sb_zhenji','yj_zhenji'],
|
zhenji:['zhenji','re_zhenji','sb_zhenji','yj_zhenji'],
|
||||||
xuzhu:['xuzhu','re_xuzhu'],
|
xuzhu:['xuzhu','re_xuzhu'],
|
||||||
|
@ -2335,15 +2338,15 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
liubei:['liubei','re_liubei','sb_liubei','dc_liubei','junk_liubei'],
|
liubei:['liubei','re_liubei','sb_liubei','dc_liubei','junk_liubei'],
|
||||||
guanyu:['guanyu','re_guanyu','ps_guanyu','old_guanyu'],
|
guanyu:['guanyu','re_guanyu','ps_guanyu','old_guanyu'],
|
||||||
zhangfei:['zhangfei','re_zhangfei','old_zhangfei','xin_zhangfei','sb_zhangfei','tw_zhangfei','jsrg_zhangfei','yj_zhangfei'],
|
zhangfei:['zhangfei','re_zhangfei','old_zhangfei','xin_zhangfei','sb_zhangfei','tw_zhangfei','jsrg_zhangfei','yj_zhangfei'],
|
||||||
zhaoyun:['zhaoyun','re_zhaoyun','old_zhaoyun','sb_zhaoyun','ps2063_zhaoyun','ps2067_zhaoyun'],
|
zhaoyun:['zhaoyun','re_zhaoyun','old_zhaoyun','sb_zhaoyun','jsrg_zhaoyun','ps2063_zhaoyun','ps2067_zhaoyun'],
|
||||||
sp_zhaoyun:['sp_zhaoyun','jsp_zhaoyun'],
|
sp_zhaoyun:['sp_zhaoyun','jsp_zhaoyun'],
|
||||||
machao:['machao','re_machao','sb_machao','ps_machao'],
|
machao:['machao','re_machao','sb_machao','ps_machao'],
|
||||||
sp_machao:['sp_machao','dc_sp_machao','jsrg_machao','old_machao'],
|
sp_machao:['sp_machao','dc_sp_machao','jsrg_machao','old_machao'],
|
||||||
zhugeliang:['zhugeliang','re_zhugeliang','ps2066_zhugeliang','ps_zhugeliang','sb_zhugeliang'],
|
zhugeliang:['zhugeliang','re_zhugeliang','sb_zhugeliang','jsrg_zhugeliang','ps2066_zhugeliang','ps_zhugeliang'],
|
||||||
huangyueying:['huangyueying','re_huangyueying','junk_huangyueying','sb_huangyueying'],
|
huangyueying:['huangyueying','re_huangyueying','junk_huangyueying','sb_huangyueying'],
|
||||||
sunquan:['sunquan','re_sunquan','sb_sunquan','dc_sunquan'],
|
sunquan:['sunquan','re_sunquan','sb_sunquan','dc_sunquan'],
|
||||||
zhouyu:['zhouyu','re_zhouyu','sb_zhouyu','ps1062_zhouyu','ps2080_zhouyu'],
|
zhouyu:['zhouyu','re_zhouyu','sb_zhouyu','ps1062_zhouyu','ps2080_zhouyu'],
|
||||||
luxun:['luxun','re_luxun'],
|
luxun:['luxun','re_luxun','jsrg_luxun'],
|
||||||
lvmeng:['lvmeng','re_lvmeng','sb_lvmeng'],
|
lvmeng:['lvmeng','re_lvmeng','sb_lvmeng'],
|
||||||
huanggai:['huanggai','re_huanggai','sb_huanggai'],
|
huanggai:['huanggai','re_huanggai','sb_huanggai'],
|
||||||
daqiao:['daqiao','re_daqiao','sb_daqiao'],
|
daqiao:['daqiao','re_daqiao','sb_daqiao'],
|
||||||
|
|
|
@ -77,7 +77,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
tw_madai:['male','shu',4,['mashu','twqianxi']],
|
tw_madai:['male','shu',4,['mashu','twqianxi']],
|
||||||
tw_niujin:['male','wei',4,['twcuorui','twliewei']],
|
tw_niujin:['male','wei',4,['twcuorui','twliewei']],
|
||||||
tw_guanqiujian:['male','wei',3,['twzhengrong','twhongju']],
|
tw_guanqiujian:['male','wei',3,['twzhengrong','twhongju']],
|
||||||
tw_daxiaoqiao:['female','wu',3,['twxingwu','twpingting']],
|
tw_daxiaoqiao:['female','wu',3,['twxingwu','twpingting'],['tempname:daxiaoqiao']],
|
||||||
tw_furong:['male','shu',4,['twxuewei','twliechi']],
|
tw_furong:['male','shu',4,['twxuewei','twliechi']],
|
||||||
tw_yl_luzhi:['male','qun',3,['twmingren','twzhenliang']],
|
tw_yl_luzhi:['male','qun',3,['twmingren','twzhenliang']],
|
||||||
tw_liuzhang:['male','qun',3,['jutu','twyaohu','rehuaibi']],
|
tw_liuzhang:['male','qun',3,['jutu','twyaohu','rehuaibi']],
|
||||||
|
@ -364,12 +364,12 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
event.target=target;
|
event.target=target;
|
||||||
var list=['cancel2'];
|
var list=['cancel2'];
|
||||||
var choiceList=[
|
var choiceList=[
|
||||||
'弃置一张手牌,令此【杀】可以额外指定一个目标',
|
'令此【杀】可以额外指定一个目标',
|
||||||
'弃置其一张手牌,若此【杀】造成伤害,则你摸一张牌且本阶段可以额外使用一张【杀】',
|
'弃置其一张手牌,若此【杀】造成伤害,则你摸一张牌且本阶段可以额外使用一张【杀】',
|
||||||
];
|
];
|
||||||
if(target.countCards('h')) list.unshift('其弃置');
|
if(target.countCards('h')) list.unshift('其弃置');
|
||||||
else choiceList[1]='<span style="opacity:0.5">'+choiceList[1]+'</span>';
|
else choiceList[1]='<span style="opacity:0.5">'+choiceList[1]+'</span>';
|
||||||
if(game.hasPlayer(targetx=>!trigger.targets.includes(targetx)&&player.canUse(trigger.card,targetx))) list.unshift('你弃置');
|
if(game.hasPlayer(targetx=>!trigger.targets.includes(targetx)&&player.canUse(trigger.card,targetx))) list.unshift('多指');
|
||||||
else choiceList[0]='<span style="opacity:0.5">'+choiceList[0]+'</span>';
|
else choiceList[0]='<span style="opacity:0.5">'+choiceList[0]+'</span>';
|
||||||
player.chooseControl(list).set('choiceList',choiceList).set('ai',()=>{
|
player.chooseControl(list).set('choiceList',choiceList).set('ai',()=>{
|
||||||
var controls=_status.event.controls;
|
var controls=_status.event.controls;
|
||||||
|
@ -377,7 +377,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
var player=trigger.player;
|
var player=trigger.player;
|
||||||
var target=trigger.target;
|
var target=trigger.target;
|
||||||
if(controls.includes('其弃置')&&_status.event.goon) return '其弃置';
|
if(controls.includes('其弃置')&&_status.event.goon) return '其弃置';
|
||||||
if(controls.includes('你弃置')){
|
if(controls.includes('多指')){
|
||||||
if(game.hasPlayer(targetx=>!trigger.targets.includes(targetx)&&player.canUse(trigger.card,targetx)&&get.effect(targetx,trigger.card,player,player)>0)) return '你弃置';
|
if(game.hasPlayer(targetx=>!trigger.targets.includes(targetx)&&player.canUse(trigger.card,targetx)&&get.effect(targetx,trigger.card,player,player)>0)) return '你弃置';
|
||||||
}
|
}
|
||||||
return 'cancel2';
|
return 'cancel2';
|
||||||
|
@ -6240,7 +6240,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
audio:2,
|
audio:2,
|
||||||
trigger:{global:['roundStart','dying']},
|
trigger:{global:['roundStart','dying']},
|
||||||
init:function(player,skill){
|
init:function(player,skill){
|
||||||
if(player.getExpansions('twxingwu').length) player.addAdditionalSkill(skill,['tianxiang_daxiaoqiao','liuli_daxiaoqiao']);
|
if(player.getExpansions('twxingwu').length) player.addAdditionalSkill(skill,['tianxiang','liuli']);
|
||||||
else player.removeAdditionalSkill(skill);
|
else player.removeAdditionalSkill(skill);
|
||||||
},
|
},
|
||||||
filter:function(event,player){
|
filter:function(event,player){
|
||||||
|
@ -6269,18 +6269,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
},
|
},
|
||||||
subSkill:{
|
subSkill:{
|
||||||
update:{
|
update:{
|
||||||
trigger:{
|
trigger:{player:['loseAfter','loseAsyncAfter','addToExpansionAfter']},
|
||||||
player:['loseAfter','loseAsyncAfter','addToExpansionAfter'],
|
filter:function(event,player){
|
||||||
|
var cards=player.getExpansions('twxingwu'),skills=player.additionalSkills.twpingting;
|
||||||
|
return !((cards.length&&skills&&skills.length)||(!cards.length&&(!skills||!skills.length)));
|
||||||
},
|
},
|
||||||
forced:true,
|
forced:true,
|
||||||
silent:true,
|
silent:true,
|
||||||
filter:function(event,player){
|
|
||||||
var cards=player.getExpansions('twxingwu'),skills=player.additionalSkills.twpingting;
|
|
||||||
if((cards.length&&skills&&skills.length)||(!cards.length&&(!skills||!skills.length))){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
content:function(){
|
content:function(){
|
||||||
lib.skill.twpingting.init(player,'twpingting');
|
lib.skill.twpingting.init(player,'twpingting');
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
dc_sp_machao:['male','qun',4,['zhuiji','dc_olshichou']],
|
dc_sp_machao:['male','qun',4,['zhuiji','dc_olshichou']],
|
||||||
old_huangfusong:['male','qun',4,['xinfenyue']],
|
old_huangfusong:['male','qun',4,['xinfenyue']],
|
||||||
dc_xiahouba:['male','shu',4,['rebaobian']],
|
dc_xiahouba:['male','shu',4,['rebaobian']],
|
||||||
dc_daxiaoqiao:['female','wu',3,['dcxingwu','dcluoyan']],
|
dc_daxiaoqiao:['female','wu',3,['dcxingwu','dcluoyan'],['tempname:daxiaoqiao']],
|
||||||
tianshangyi:['female','wei',3,['dcposuo','dcxiaoren']],
|
tianshangyi:['female','wei',3,['dcposuo','dcxiaoren']],
|
||||||
sunlingluan:['female','wu',3,['dclingyue','dcpandi']],
|
sunlingluan:['female','wu',3,['dclingyue','dcpandi']],
|
||||||
dc_wangjun:['male','qun',4,['dctongye','dcchangqu']],
|
dc_wangjun:['male','qun',4,['dctongye','dcchangqu']],
|
||||||
|
@ -145,10 +145,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
return (dis?6:1)-get.useful(card);
|
return (dis?6:1)-get.useful(card);
|
||||||
}
|
}
|
||||||
if(_status.event.hvt.includes(card)){
|
if(_status.event.hvt.includes(card)){
|
||||||
if(_status.event.suits.length>=4){
|
|
||||||
if(cards.length>8) return 0;
|
|
||||||
return 4.5-get.value(card);
|
|
||||||
}
|
|
||||||
if(!_status.event.suits.includes(suit)) return 6-get.value(card);
|
if(!_status.event.suits.includes(suit)) return 6-get.value(card);
|
||||||
if(card.name==='sha') return 3-get.value(card);
|
if(card.name==='sha') return 3-get.value(card);
|
||||||
return 1-get.value(card);
|
return 1-get.value(card);
|
||||||
|
@ -1306,6 +1302,17 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
},
|
},
|
||||||
dczhangcai:{
|
dczhangcai:{
|
||||||
audio:2,
|
audio:2,
|
||||||
|
mod:{
|
||||||
|
aiOrder:(player,card,num)=>{
|
||||||
|
if(num>0&&get.tag(card,'draw')&&ui.cardPile.childNodes.length+ui.discardPile.childNodes.length<20) return 0;
|
||||||
|
},
|
||||||
|
aiValue:(player,card,num)=>{
|
||||||
|
if(num>0&&card.name==='zhuge') return 20;
|
||||||
|
},
|
||||||
|
aiUseful:(player,card,num)=>{
|
||||||
|
if(num>0&&card.name==='zhuge') return 10;
|
||||||
|
}
|
||||||
|
},
|
||||||
trigger:{
|
trigger:{
|
||||||
player:['useCard','respond'],
|
player:['useCard','respond'],
|
||||||
},
|
},
|
||||||
|
@ -1319,7 +1326,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
if(typeof num=='number') count=Math.max(1,player.countCards('h',card=>get.number(card)==num))
|
if(typeof num=='number') count=Math.max(1,player.countCards('h',card=>get.number(card)==num))
|
||||||
return '你可以摸'+get.cnNumber(count)+'张牌。';
|
return '你可以摸'+get.cnNumber(count)+'张牌。';
|
||||||
},
|
},
|
||||||
|
check:(event,player)=>{
|
||||||
|
const num=player.hasSkill('dczhangcai_all')?get.number(event.card):8;
|
||||||
|
let count=1;
|
||||||
|
if(typeof num=='number') count=Math.max(1,player.countCards('h',card=>get.number(card)==num));
|
||||||
|
return ui.cardPile.childNodes.length+ui.discardPile.childNodes.length>=count;
|
||||||
|
},
|
||||||
frequent:true,
|
frequent:true,
|
||||||
|
locked:false,
|
||||||
content:function(){
|
content:function(){
|
||||||
var num=player.hasSkill('dczhangcai_all')?get.number(trigger.card):8;
|
var num=player.hasSkill('dczhangcai_all')?get.number(trigger.card):8;
|
||||||
var count=1;
|
var count=1;
|
||||||
|
@ -1649,33 +1663,29 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dcluoyan: {
|
dcluoyan:{
|
||||||
derivation: ['retianxiang', 'liuli'],
|
derivation:['retianxiang','liuli'],
|
||||||
init: function (player) {
|
init:function(player){
|
||||||
if (player.getStorage('dcxingwu').length) player.addAdditionalSkill('dcluoyan', ['retianxiang_daxiaoqiao', 'liuli_daxiaoqiao']);
|
if(player.getExpansions('dcxingwu').length) player.addAdditionalSkill('dcluoyan',['retianxiang','liuli']);
|
||||||
else player.removeAdditionalSkill('dcluoyan');
|
else player.removeAdditionalSkill('dcluoyan');
|
||||||
},
|
},
|
||||||
onremove: function (player) {
|
onremove:function(player){
|
||||||
player.removeAdditionalSkill('dcluoyan');
|
player.removeAdditionalSkill('dcluoyan');
|
||||||
},
|
},
|
||||||
trigger: {
|
trigger:{player:['loseAfter','loseAsyncAfter','addToExpansionAfter']},
|
||||||
player: ['loseAfter', 'loseAsyncAfter', 'addToExpansionAfter'],
|
filter:function(event,player){
|
||||||
|
var cards=player.getExpansions('dcxingwu'),skills=player.additionalSkills.dcluoyan;
|
||||||
|
return !((cards.length&&skills&&skills.length)||(!cards.length&&(!skills||!skills.length)));
|
||||||
},
|
},
|
||||||
filter: function (event, player) {
|
forced:true,
|
||||||
var cards = player.getExpansions('dcxingwu'), skills = player.additionalSkills.dcluoyan;
|
silent:true,
|
||||||
if ((cards.length && skills && skills.length) || (!cards.length && (!skills || !skills.length))) {
|
content:function(){
|
||||||
return false;
|
lib.skill.dcluoyan.init(player,'dcluoyan');
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
forced: true,
|
|
||||||
content: function () {
|
|
||||||
lib.skill.twpingting.init(player, 'dcluoyan');
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
retianxiang_daxiaoqiao: {
|
retianxiang_daxiaoqiao:{
|
||||||
audio: 'tianxiang_daxiaoqiao',
|
audio:'tianxiang_daxiaoqiao',
|
||||||
inherit: 'retianxiang',
|
inherit:'retianxiang',
|
||||||
},
|
},
|
||||||
//田尚衣
|
//田尚衣
|
||||||
dcposuo:{
|
dcposuo:{
|
||||||
|
@ -13514,7 +13524,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
|
||||||
fengfangnv:['fengfangnv','re_fengfangnv'],
|
fengfangnv:['fengfangnv','re_fengfangnv'],
|
||||||
luotong:['dc_luotong','luotong'],
|
luotong:['dc_luotong','luotong'],
|
||||||
dc_wangchang:['dc_wangchang','tw_wangchang'],
|
dc_wangchang:['dc_wangchang','tw_wangchang'],
|
||||||
guozhao:['guozhao','xin_guozhao'],
|
guozhao:['guozhao','xin_guozhao','jsrg_guozhao'],
|
||||||
dingshangwan:['dingshangwan','ol_dingshangwan'],
|
dingshangwan:['dingshangwan','ol_dingshangwan'],
|
||||||
},
|
},
|
||||||
translate:{
|
translate:{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
window.noname_asset_list=[
|
window.noname_asset_list=[
|
||||||
'v1.10.6',
|
'v1.10.6.1',
|
||||||
/*audio start*/
|
/*audio start*/
|
||||||
'audio/background/aozhan_chaoming.mp3',
|
'audio/background/aozhan_chaoming.mp3',
|
||||||
'audio/background/aozhan_online.mp3',
|
'audio/background/aozhan_online.mp3',
|
||||||
|
@ -7237,30 +7237,41 @@ window.noname_asset_list=[
|
||||||
'image/character/jsp_liubei.jpg',
|
'image/character/jsp_liubei.jpg',
|
||||||
'image/character/jsp_zhaoyun.jpg',
|
'image/character/jsp_zhaoyun.jpg',
|
||||||
'image/character/jsrg_caocao.jpg',
|
'image/character/jsrg_caocao.jpg',
|
||||||
|
'image/character/jsrg_caofang.jpg',
|
||||||
'image/character/jsrg_chendeng.jpg',
|
'image/character/jsrg_chendeng.jpg',
|
||||||
'image/character/jsrg_chunyuqiong.jpg',
|
'image/character/jsrg_chunyuqiong.jpg',
|
||||||
'image/character/jsrg_dongbai.jpg',
|
'image/character/jsrg_dongbai.jpg',
|
||||||
'image/character/jsrg_fanjiangzhangda.jpg',
|
'image/character/jsrg_fanjiangzhangda.jpg',
|
||||||
|
'image/character/jsrg_gaoxiang.jpg',
|
||||||
'image/character/jsrg_guanyu.jpg',
|
'image/character/jsrg_guanyu.jpg',
|
||||||
'image/character/jsrg_guojia.jpg',
|
'image/character/jsrg_guojia.jpg',
|
||||||
|
'image/character/jsrg_guoxun.jpg',
|
||||||
|
'image/character/jsrg_guozhao.jpg',
|
||||||
'image/character/jsrg_hansui.jpg',
|
'image/character/jsrg_hansui.jpg',
|
||||||
'image/character/jsrg_hejin.jpg',
|
'image/character/jsrg_hejin.jpg',
|
||||||
'image/character/jsrg_huangfusong.jpg',
|
'image/character/jsrg_huangfusong.jpg',
|
||||||
'image/character/jsrg_huangzhong.jpg',
|
'image/character/jsrg_huangzhong.jpg',
|
||||||
|
'image/character/jsrg_jiangwei.jpg',
|
||||||
'image/character/jsrg_kongrong.jpg',
|
'image/character/jsrg_kongrong.jpg',
|
||||||
'image/character/jsrg_liubei.jpg',
|
'image/character/jsrg_liubei.jpg',
|
||||||
'image/character/jsrg_liuhong.jpg',
|
'image/character/jsrg_liuhong.jpg',
|
||||||
'image/character/jsrg_liuyan.jpg',
|
'image/character/jsrg_liuyan.jpg',
|
||||||
|
'image/character/jsrg_liuyong.jpg',
|
||||||
'image/character/jsrg_lougui.jpg',
|
'image/character/jsrg_lougui.jpg',
|
||||||
|
'image/character/jsrg_luxun.jpg',
|
||||||
'image/character/jsrg_lvbu.jpg',
|
'image/character/jsrg_lvbu.jpg',
|
||||||
'image/character/jsrg_machao.jpg',
|
'image/character/jsrg_machao.jpg',
|
||||||
'image/character/jsrg_nanhualaoxian.jpg',
|
'image/character/jsrg_nanhualaoxian.jpg',
|
||||||
'image/character/jsrg_pangtong.jpg',
|
'image/character/jsrg_pangtong.jpg',
|
||||||
'image/character/jsrg_qiaoxuan.jpg',
|
'image/character/jsrg_qiaoxuan.jpg',
|
||||||
|
'image/character/jsrg_simayi.jpg',
|
||||||
'image/character/jsrg_sunce.jpg',
|
'image/character/jsrg_sunce.jpg',
|
||||||
'image/character/jsrg_sunjian.jpg',
|
'image/character/jsrg_sunjian.jpg',
|
||||||
|
'image/character/jsrg_sunjun.jpg',
|
||||||
|
'image/character/jsrg_sunlubansunluyu.jpg',
|
||||||
'image/character/jsrg_sunshangxiang.jpg',
|
'image/character/jsrg_sunshangxiang.jpg',
|
||||||
'image/character/jsrg_wangyun.jpg',
|
'image/character/jsrg_wangyun.jpg',
|
||||||
|
'image/character/jsrg_weiwenzhugezhi.jpg',
|
||||||
'image/character/jsrg_xiahouen.jpg',
|
'image/character/jsrg_xiahouen.jpg',
|
||||||
'image/character/jsrg_xiahourong.jpg',
|
'image/character/jsrg_xiahourong.jpg',
|
||||||
'image/character/jsrg_xugong.jpg',
|
'image/character/jsrg_xugong.jpg',
|
||||||
|
@ -7272,7 +7283,10 @@ window.noname_asset_list=[
|
||||||
'image/character/jsrg_zhanghe.jpg',
|
'image/character/jsrg_zhanghe.jpg',
|
||||||
'image/character/jsrg_zhangliao.jpg',
|
'image/character/jsrg_zhangliao.jpg',
|
||||||
'image/character/jsrg_zhangren.jpg',
|
'image/character/jsrg_zhangren.jpg',
|
||||||
|
'image/character/jsrg_zhangxuan.jpg',
|
||||||
|
'image/character/jsrg_zhaoyun.jpg',
|
||||||
'image/character/jsrg_zhenji.jpg',
|
'image/character/jsrg_zhenji.jpg',
|
||||||
|
'image/character/jsrg_zhugeliang.jpg',
|
||||||
'image/character/jsrg_zhujun.jpg',
|
'image/character/jsrg_zhujun.jpg',
|
||||||
'image/character/jsrg_zoushi.jpg',
|
'image/character/jsrg_zoushi.jpg',
|
||||||
'image/character/jun_caocao.jpg',
|
'image/character/jun_caocao.jpg',
|
||||||
|
|
|
@ -91,7 +91,7 @@ new Promise(resolve => {
|
||||||
script.async = true
|
script.async = true
|
||||||
script.onerror = (event) => {
|
script.onerror = (event) => {
|
||||||
console.error(event)
|
console.error(event)
|
||||||
const message = `您使用的浏览器或无名杀客户端加载内容失败!\n若您使用的客户端为自带内核的旧版“兼容版”,请及时更新客户端版本!\n若您使用的客户端为手机端的非兼容版无名杀,请尝试更新手机端WebView内核,或者更换为1.8.2版本以上的兼容版!`;
|
const message = `您使用的浏览器或《无名杀》客户端加载内容失败!\n若您使用的客户端为自带内核的旧版“兼容版”,请及时更新客户端版本!\n若您使用的客户端为手机端的非兼容版《无名杀》,请尝试更新手机的WebView内核,或者更换为1.8.2版本及以上的兼容版!\n若您是直接使用浏览器加载index.html进行游戏,请改为运行文件夹内的“noname-server.exe”(或使用VSCode等工具启动Live Server),以动态服务器的方式启动《无名杀》!`;
|
||||||
console.error(message);
|
console.error(message);
|
||||||
alert(message);
|
alert(message);
|
||||||
exit()
|
exit()
|
||||||
|
|
101
game/update.js
|
@ -1,137 +1,56 @@
|
||||||
window.noname_update={
|
window.noname_update={
|
||||||
version:'1.10.6',
|
version:'1.10.6.1',
|
||||||
update:'1.10.5',
|
update:'1.10.6',
|
||||||
changeLog:[
|
changeLog:[
|
||||||
'整合@nonameShijian @mengxinzxz @PZ157 @Ansolve @Rintim @S-N-O-R-L-A-X @universe-st @copcap @kuangshen04 的Pull Request',
|
'整合@mengxinzxz @PZ157 @universe-st @Ansolve @Rintim @nonameShijian @copcap @kuangshen04 的Pull Request',
|
||||||
'拆分game.js,优化代码逻辑与可读性',
|
'《江山如故·合》武将包',
|
||||||
'孙策(十周年斗地主)、乐小乔、手杀陈珪、手杀胡班、OL界凌统、OL界曹彰、OL界简雍、OL谋姜维、谋诸葛亮、谋关羽、曹宇、星董卓、曹宪、新杀谋鲁肃、新杀谋周瑜',
|
|
||||||
'其他AI优化与bug修复',
|
'其他AI优化与bug修复',
|
||||||
],
|
],
|
||||||
files:[
|
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/standard.js',
|
||||||
'card/swd.js',
|
|
||||||
'card/yingbian.js',
|
|
||||||
'card/yongjian.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/extra.js',
|
||||||
'character/gujian.js',
|
|
||||||
'character/gwent.js',
|
|
||||||
'character/hearth.js',
|
|
||||||
'character/huicui.js',
|
'character/huicui.js',
|
||||||
'character/jiange.js',
|
|
||||||
'character/jsrg.js',
|
'character/jsrg.js',
|
||||||
'character/mobile.js',
|
'character/mobile.js',
|
||||||
'character/mtg.js',
|
|
||||||
'character/offline.js',
|
'character/offline.js',
|
||||||
'character/old.js',
|
|
||||||
'character/onlyOL.js',
|
|
||||||
'character/ow.js',
|
|
||||||
'character/rank.js',
|
'character/rank.js',
|
||||||
'character/refresh.js',
|
'character/refresh.js',
|
||||||
'character/sb.js',
|
'character/sb.js',
|
||||||
'character/shenhua.js',
|
'character/shenhua.js',
|
||||||
'character/shiji.js',
|
|
||||||
'character/sp.js',
|
'character/sp.js',
|
||||||
'character/sp2.js',
|
'character/sp2.js',
|
||||||
'character/standard.js',
|
'character/standard.js',
|
||||||
'character/swd.js',
|
|
||||||
'character/tw.js',
|
'character/tw.js',
|
||||||
'character/xiake.js',
|
|
||||||
'character/xianding.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/game.js',
|
||||||
'game/package.js',
|
|
||||||
'game/source.js',
|
'game/source.js',
|
||||||
|
|
||||||
'mode/boss.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.js',
|
||||||
|
|
||||||
'noname/ai/basic.js',
|
|
||||||
'noname/ai/index.js',
|
|
||||||
'noname/game/index.js',
|
'noname/game/index.js',
|
||||||
'noname/game/promises.js',
|
|
||||||
'noname/game/dynamic-style/index.js',
|
|
||||||
'noname/get/index.js',
|
'noname/get/index.js',
|
||||||
'noname/get/is.js',
|
'noname/get/is.js',
|
||||||
'noname/gnc/index.js',
|
|
||||||
'noname/gnc/is.js',
|
|
||||||
'noname/init/cordova.js',
|
'noname/init/cordova.js',
|
||||||
'noname/init/import.js',
|
'noname/init/import.js',
|
||||||
'noname/init/index.js',
|
'noname/init/index.js',
|
||||||
'noname/init/node.js',
|
|
||||||
'noname/init/onload.js',
|
|
||||||
'noname/init/polyfill.js',
|
|
||||||
'noname/library/index.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/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/gameEvent.js',
|
||||||
'noname/library/element/gameEventPromise.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/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/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/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',
|
'noname/util/struct/promise-error-handler/unknown.js',
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 102 KiB |
119
index.html
|
@ -7,7 +7,7 @@
|
||||||
<title>无名杀</title>
|
<title>无名杀</title>
|
||||||
<script>
|
<script>
|
||||||
window.onerror = function (msg, src, line, column, err) {
|
window.onerror = function (msg, src, line, column, err) {
|
||||||
var str = `错误文件: ${typeof src == 'string' && src.length > 0 ? decodeURI(src) : '未知文件'}`;
|
let str = `错误文件: ${typeof src == 'string' && src.length > 0 ? decodeURI(src) : '未知文件'}`;
|
||||||
str += `\n错误信息: ${msg}`;
|
str += `\n错误信息: ${msg}`;
|
||||||
str += `\n行号: ${line}`;
|
str += `\n行号: ${line}`;
|
||||||
str += `\n列号: ${column}`;
|
str += `\n列号: ${column}`;
|
||||||
|
@ -16,6 +16,123 @@
|
||||||
alert(str);
|
alert(str);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
if (location.href.startsWith('http') && typeof window.initReadWriteFunction != 'function' && !window.require && !window.__dirname) {
|
||||||
|
window.initReadWriteFunction = function(game) {
|
||||||
|
/*game.download = function() {
|
||||||
|
// 暂不实现
|
||||||
|
};*/
|
||||||
|
|
||||||
|
game.createDir = function (dir, success = () => {}, error = () => {}) {
|
||||||
|
fetch(`./createDir?dir=${dir}`)
|
||||||
|
.then(response => {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
if (result && result.success) success();
|
||||||
|
else error();
|
||||||
|
})
|
||||||
|
.catch(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
game.readFile = function (fileName, callback = () => {}, error = () => {}) {
|
||||||
|
fetch(`./readFile?fileName=${fileName}`)
|
||||||
|
.then(response => {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
if (result && result.success) callback(new Uint8Array(result.data).buffer);
|
||||||
|
else error(result && result.errorMsg);
|
||||||
|
})
|
||||||
|
.catch(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
game.readFileAsText = function (fileName, callback = () => {}, error = () => {}) {
|
||||||
|
fetch(`./readFileAsText?fileName=${fileName}`)
|
||||||
|
.then(response => {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
if (result && result.success) callback(result.data);
|
||||||
|
else error(result && result.errorMsg);
|
||||||
|
})
|
||||||
|
.catch(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
game.writeFile = function (data, path, name, callback = () => { }) {
|
||||||
|
game.ensureDirectory(path, function () {
|
||||||
|
if (Object.prototype.toString.call(data) == '[object File]') {
|
||||||
|
const fileReader = new FileReader();
|
||||||
|
fileReader.onload = function (e) {
|
||||||
|
game.writeFile(e.target.result, path, name, callback);
|
||||||
|
};
|
||||||
|
fileReader.readAsArrayBuffer(data, "UTF-8");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let filePath = path;
|
||||||
|
if (path.endsWith('/')) {
|
||||||
|
filePath += name;
|
||||||
|
} else if (path == "") {
|
||||||
|
filePath += name;
|
||||||
|
} else {
|
||||||
|
filePath += '/' + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(`./writeFile`, {
|
||||||
|
method: 'post',
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
data: typeof data == 'string' ? data : Array.prototype.slice.call(new Uint8Array(data)),
|
||||||
|
path: filePath
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
if (result && result.success) {
|
||||||
|
callback();
|
||||||
|
} else {
|
||||||
|
callback(result.errorMsg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
game.removeFile = function (fileName, callback = () => {}) {
|
||||||
|
fetch(`./removeFile?fileName=${fileName}`)
|
||||||
|
.then(response => {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
callback(result.errorMsg);
|
||||||
|
})
|
||||||
|
.catch(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
game.getFileList = function (dir, callback = () => {}) {
|
||||||
|
fetch(`./getFileList?dir=${dir}`)
|
||||||
|
.then(response => {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
if (result && result.success) {
|
||||||
|
callback(result.data.dirs, result.data.files);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
game.ensureDirectory = function (list, callback = () => {}, file = false) {
|
||||||
|
let pathArray = typeof list == "string" ? list.split("/") : list;
|
||||||
|
if (file) {
|
||||||
|
pathArray = pathArray.slice(0, -1);
|
||||||
|
}
|
||||||
|
game.createDir(pathArray.join("/"), callback, console.error);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<script src="game/update.js"></script>
|
<script src="game/update.js"></script>
|
||||||
<script src="game/config.js"></script>
|
<script src="game/config.js"></script>
|
||||||
<script src="game/package.js"></script>
|
<script src="game/package.js"></script>
|
||||||
|
|
|
@ -8818,7 +8818,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
|
||||||
}
|
}
|
||||||
function isDefined(opd) {
|
function isDefined(opd) {
|
||||||
if(opd!=undefined){
|
if(opd!=undefined){
|
||||||
if (opd.get||opd.set||opd.writable!=true||opd.configurable!=true||opd.enumerable!=true){
|
if (opd.get||opd.set||opd.writable!=true||opd.configurable!=true){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
declare type CardBaseUIData = {
|
||||||
|
name?: string;
|
||||||
|
suit?: string;
|
||||||
|
number?: number;
|
||||||
|
nature?: string;
|
||||||
|
|
||||||
|
//用于某些方法,用于过滤卡牌的额外结构
|
||||||
|
type?: string;
|
||||||
|
subtype?: string;
|
||||||
|
color?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否时视为牌
|
||||||
|
*
|
||||||
|
* 是本来的卡牌,则为true,作为视为牌则为false/undefined
|
||||||
|
* 在useCard使用时,作为视为牌,会把next.cards,设置为card.cards;
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
isCard?: boolean;
|
||||||
|
|
||||||
|
/** 真实使用的卡牌 */
|
||||||
|
cards?: Card[];
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
declare interface Result {
|
||||||
|
/**
|
||||||
|
* 最终结果
|
||||||
|
*
|
||||||
|
* 大多代表该事件到达这一步骤过程中的结果;
|
||||||
|
* 一般用来标记当前事件是否按预定执行的,即执行成功
|
||||||
|
*
|
||||||
|
* 大部分事件间接接触game.check,一般最终结果不变,大多数是这种
|
||||||
|
*
|
||||||
|
* 其实主要是ok方法会有直接的bool,主要涉及game.check;
|
||||||
|
*/
|
||||||
|
bool?: boolean;
|
||||||
|
|
||||||
|
//choose系
|
||||||
|
/** 记录返回当前事件操作过程中的卡牌 */
|
||||||
|
cards: Card[];
|
||||||
|
/** 记录返回当前事件操作过程中的目标 */
|
||||||
|
targets: Player[];
|
||||||
|
/** 记录返回当前事件操作过程中的按钮 */
|
||||||
|
buttons: Button[];
|
||||||
|
/** 记录buttons内所有button.link(即该按钮的类型,link的类型很多,参考按钮的item) */
|
||||||
|
links: any[];
|
||||||
|
|
||||||
|
//control系(直接control系列没有result.bool)
|
||||||
|
/** control操作面板的选中结果,即该按钮的link,即名字 */
|
||||||
|
control: string;
|
||||||
|
/** 既control的下标 */
|
||||||
|
index: number;
|
||||||
|
|
||||||
|
//ok系
|
||||||
|
/** 记录返回当前事件操作过程中,面板按钮的确定ok取消cancel */
|
||||||
|
confirm: string;
|
||||||
|
/** 一般为触发的“视为”技能 */
|
||||||
|
skill: string;
|
||||||
|
/**
|
||||||
|
* 当前事件操作的“视为”牌,
|
||||||
|
* 当前有“视为”操作,该card参数特供给视为牌,不需要cards[0]获取视为牌 ;
|
||||||
|
* 判断是否为视为牌:card.isCard,false为视为牌
|
||||||
|
*/
|
||||||
|
card: Card;
|
||||||
|
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
/// <reference path="./ArrayEx.d.ts" />
|
/// <reference path="./ArrayEx.d.ts" />
|
||||||
|
/// <reference path="./Card.d.ts" />
|
||||||
/// <reference path="./DateEx.d.ts" />
|
/// <reference path="./DateEx.d.ts" />
|
||||||
/// <reference path="./HTMLDivElementEx.d.ts" />
|
/// <reference path="./HTMLDivElementEx.d.ts" />
|
||||||
/// <reference path="./HTMLTableELementEx.d.ts" />
|
/// <reference path="./HTMLTableELementEx.d.ts" />
|
||||||
/// <reference path="./windowEx.d.ts" />
|
/// <reference path="./windowEx.d.ts" />
|
||||||
|
/// <reference path="./Result.d.ts" />
|
||||||
|
/// <reference path="./Skill.d.ts" />
|
||||||
/// <reference path="./type.d.ts" />
|
/// <reference path="./type.d.ts" />
|
||||||
/// <reference path="./MapEx.d.ts" />
|
/// <reference path="./MapEx.d.ts" />
|
||||||
/// <reference types="@types/cordova" />
|
/// <reference types="@types/cordova" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "noname-typings",
|
"name": "noname-typings",
|
||||||
"version": "2023.12.31",
|
"version": "2024.01.16",
|
||||||
"description": "Noname typings, mainly for showing type hints when creating extensions of the Sanguosha-like game Noname.",
|
"description": "Noname typings, mainly for showing type hints when creating extensions of the Sanguosha-like game Noname.",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -17,15 +17,43 @@ interface NMap<V> {
|
||||||
[key: number]: V
|
[key: number]: V
|
||||||
}
|
}
|
||||||
|
|
||||||
declare type Game = import('../../noname/game/index.js').Game;
|
//从0个参数到任意参数的方法结构声明
|
||||||
declare type Library = import('../../noname/library/index.js').Library;
|
type NoneParmFum<T> = () => T;
|
||||||
|
type OneParmFun<U, T> = (arg0: U) => T;
|
||||||
|
type TwoParmFun<U1, U2, T> = (arg0: U1, arg1: U2) => T;
|
||||||
|
type ThreeParmFun<U1, U2, U3, T> = (arg0: U1, arg1: U2, arg2: U3) => T;
|
||||||
|
type FourParmFun<U1, U2, U3, U4, T> = (arg0: U1, arg1: U2, arg2: U3, arg3: U4) => T;
|
||||||
|
type RestParmFun<T> = (...args) => T;
|
||||||
|
type RestParmFun2<U, T> = (...args: U[]) => T;
|
||||||
|
|
||||||
|
//尝试增加的符合类型声明
|
||||||
|
/** SingleAndArrayType:单体与集合类型 */
|
||||||
|
type SAAType<T> = T | T[];
|
||||||
|
/** 再价格可以返回这种类型的方法 */
|
||||||
|
type SAAFType<T> = T | T[] | RestParmFun<T>;
|
||||||
|
/** 有name属性的对象 */
|
||||||
|
type NameType = { name: string };
|
||||||
|
/** 技能或者卡牌 */
|
||||||
|
type SkillOrCard = string | NameType | Card;
|
||||||
|
/** 卡牌或者卡牌集合 */
|
||||||
|
type CCards = SAAType<Card>;
|
||||||
|
|
||||||
|
/** 技能content */
|
||||||
|
declare type ContentFuncByAll = {
|
||||||
|
// (event: GameEventPromise, step: number, source: Player, player: Player, target: Player, targets: Player[], card: Card, cards: Card[], skill: string, forced: boolean, num: number, trigger: GameEventPromise, result: Result): any,
|
||||||
|
(event: GameEventPromise, trigger: GameEventPromise, player: Player): Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare type Game = typeof import('../../noname/game/index.js').Game;
|
||||||
|
declare type Library = typeof import('../../noname/library/index.js').Library;
|
||||||
declare type Status = typeof import('../../noname/status/index.js').status;
|
declare type Status = typeof import('../../noname/status/index.js').status;
|
||||||
declare type UI = import('../../noname/ui/index.js').UI;
|
declare type UI = typeof import('../../noname/ui/index.js').UI;
|
||||||
declare type Get = import('../../noname/get/index.js').Get;
|
declare type Get = typeof import('../../noname/get/index.js').Get;
|
||||||
declare type AI = import('../../noname/ai/index.js').AI;
|
declare type AI = typeof import('../../noname/ai/index.js').AI;
|
||||||
|
|
||||||
declare type Button = import('../../noname/library/index.js').Button;
|
declare type Button = import('../../noname/library/index.js').Button;
|
||||||
declare type Card = import('../../noname/library/index.js').Card;
|
declare type Card = import('../../noname/library/index.js').Card;
|
||||||
|
declare type VCard = import('../../noname/library/index.js').VCard;
|
||||||
declare type Dialog = import('../../noname/library/index.js').Dialog;
|
declare type Dialog = import('../../noname/library/index.js').Dialog;
|
||||||
declare type GameEvent = import('../../noname/library/index.js').GameEvent;
|
declare type GameEvent = import('../../noname/library/index.js').GameEvent;
|
||||||
declare type GameEventPromise = import('../../noname/library/index.js').GameEventPromise;
|
declare type GameEventPromise = import('../../noname/library/index.js').GameEventPromise;
|
||||||
|
@ -39,4 +67,5 @@ declare type GameHistory = import('../../noname/game/index.js').GameHistory;
|
||||||
declare type CodeMirror = typeof import('../../game/codemirror.js').default;
|
declare type CodeMirror = typeof import('../../game/codemirror.js').default;
|
||||||
|
|
||||||
declare type Sex = 'male' | 'female' | 'dobule' | 'none';
|
declare type Sex = 'male' | 'female' | 'dobule' | 'none';
|
||||||
declare type Character = [Sex, string, number | string, string[], string[]];
|
declare type Character = [Sex, string, number | string, string[], string[]];
|
||||||
|
declare type Select = [number, number];
|
|
@ -69,16 +69,7 @@ declare interface Window {
|
||||||
ai: AI;
|
ai: AI;
|
||||||
}
|
}
|
||||||
|
|
||||||
initReadWriteFunction?(game = ({
|
initReadWriteFunction?(game: Game): void;
|
||||||
download: () => any,
|
|
||||||
readFile: () => any,
|
|
||||||
readFileAsText: () => any,
|
|
||||||
writeFile: () => any,
|
|
||||||
removeFile: () => any,
|
|
||||||
getFileList: () => any,
|
|
||||||
ensureDirectory: () => any,
|
|
||||||
createDir: () => any,
|
|
||||||
})): void;
|
|
||||||
|
|
||||||
bannedKeyWords: string[];
|
bannedKeyWords: string[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1364,19 +1364,21 @@ export class Game extends Uninstantable {
|
||||||
else if (!path.startsWith('db:')) path = `audio/${path}`;
|
else if (!path.startsWith('db:')) path = `audio/${path}`;
|
||||||
if (!lib.config.repeat_audio && _status.skillaudio.includes(path)) return;
|
if (!lib.config.repeat_audio && _status.skillaudio.includes(path)) return;
|
||||||
}
|
}
|
||||||
_status.skillaudio.add(path);
|
|
||||||
game.addVideo('playAudio', null, path);
|
|
||||||
setTimeout(() => _status.skillaudio.remove(path), 1000);
|
|
||||||
const audio = document.createElement('audio');
|
const audio = document.createElement('audio');
|
||||||
audio.autoplay = true;
|
audio.autoplay = true;
|
||||||
audio.volume = lib.config.volumn_audio / 8;
|
audio.volume = lib.config.volumn_audio / 8;
|
||||||
audio.addEventListener('ended', () => audio.remove());
|
//Some browsers do not support "autoplay", so "oncanplay" listening has been added
|
||||||
audio.onerror = event => {
|
audio.oncanplay = () => Promise.resolve(audio.play()).catch(() => void 0);
|
||||||
|
audio.onplay = () => {
|
||||||
|
_status.skillaudio.add(path);
|
||||||
|
setTimeout(() => _status.skillaudio.remove(path), 1000);
|
||||||
|
game.addVideo("playAudio", null, path);
|
||||||
|
};
|
||||||
|
audio.onended = (event) => audio.remove();
|
||||||
|
audio.onerror = (event) => {
|
||||||
audio.remove();
|
audio.remove();
|
||||||
if (onError) onError(event);
|
if (onError) onError(event);
|
||||||
};
|
};
|
||||||
//Some browsers do not support "autoplay", so "oncanplay" listening has been added
|
|
||||||
audio.oncanplay = () => Promise.resolve(audio.play()).catch(() => void 0);
|
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
if (path.startsWith('db:')) game.getDB('image', path.slice(3)).then(octetStream => resolve(get.objectURL(octetStream)), reject);
|
if (path.startsWith('db:')) game.getDB('image', path.slice(3)).then(octetStream => resolve(get.objectURL(octetStream)), reject);
|
||||||
else if (lib.path.extname(path)) resolve(`${lib.assetURL}${path}`);
|
else if (lib.path.extname(path)) resolve(`${lib.assetURL}${path}`);
|
||||||
|
@ -4213,6 +4215,7 @@ export class Game extends Uninstantable {
|
||||||
* @param { string } skill
|
* @param { string } skill
|
||||||
* @param { Player } player
|
* @param { Player } player
|
||||||
* @param { GameEventPromise } event
|
* @param { GameEventPromise } event
|
||||||
|
* @returns { GameEventPromise }
|
||||||
*/
|
*/
|
||||||
static createTrigger(name, skill, player, event) {
|
static createTrigger(name, skill, player, event) {
|
||||||
let info = get.info(skill);
|
let info = get.info(skill);
|
||||||
|
@ -4227,6 +4230,7 @@ export class Game extends Uninstantable {
|
||||||
next.includeOut = true;
|
next.includeOut = true;
|
||||||
next._trigger = event;
|
next._trigger = event;
|
||||||
next.setContent('createTrigger');
|
next.setContent('createTrigger');
|
||||||
|
return next;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @legacy Use {@link lib.element.GameEvent.constructor} instead.
|
* @legacy Use {@link lib.element.GameEvent.constructor} instead.
|
||||||
|
@ -5362,10 +5366,11 @@ export class Game extends Uninstantable {
|
||||||
* @param { GameEventPromise } [belongAsyncEvent]
|
* @param { GameEventPromise } [belongAsyncEvent]
|
||||||
*/
|
*/
|
||||||
static async loop(belongAsyncEvent) {
|
static async loop(belongAsyncEvent) {
|
||||||
|
if (!game.belongAsyncEventList) game.belongAsyncEventList = [];
|
||||||
if (belongAsyncEvent) {
|
if (belongAsyncEvent) {
|
||||||
game.belongAsyncEvent = belongAsyncEvent;
|
game.belongAsyncEventList.push(belongAsyncEvent);
|
||||||
} else if (game.belongAsyncEvent) {
|
} else if (game.belongAsyncEventList.length) {
|
||||||
return game.loop(game.belongAsyncEvent);
|
belongAsyncEvent = game.belongAsyncEventList.at(-1);
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
let event = (belongAsyncEvent && belongAsyncEvent.parent == _status.event) ? belongAsyncEvent : _status.event;
|
let event = (belongAsyncEvent && belongAsyncEvent.parent == _status.event) ? belongAsyncEvent : _status.event;
|
||||||
|
@ -5443,8 +5448,8 @@ export class Game extends Uninstantable {
|
||||||
event.parent._result = event.result;
|
event.parent._result = event.result;
|
||||||
}
|
}
|
||||||
_status.event = event.parent;
|
_status.event = event.parent;
|
||||||
if (game.belongAsyncEvent == event) {
|
if (game.belongAsyncEventList.includes(event)) {
|
||||||
delete game.belongAsyncEvent;
|
game.belongAsyncEventList.remove(event);
|
||||||
}
|
}
|
||||||
_resolve();
|
_resolve();
|
||||||
// 此时应该退出了
|
// 此时应该退出了
|
||||||
|
@ -5453,8 +5458,8 @@ export class Game extends Uninstantable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (game.belongAsyncEvent == event) {
|
if (game.belongAsyncEventList.includes(event)) {
|
||||||
delete game.belongAsyncEvent;
|
game.belongAsyncEventList.remove(event);
|
||||||
}
|
}
|
||||||
return _resolve();
|
return _resolve();
|
||||||
}
|
}
|
||||||
|
@ -6017,7 +6022,18 @@ export class Game extends Uninstantable {
|
||||||
if (info.usable && get.skillCount(skills2[i]) >= info.usable) enable = false;
|
if (info.usable && get.skillCount(skills2[i]) >= info.usable) enable = false;
|
||||||
if (info.chooseButton && _status.event.noButton) enable = false;
|
if (info.chooseButton && _status.event.noButton) enable = false;
|
||||||
if (info.round && (info.round - (game.roundNumber - player.storage[skills2[i] + '_roundcount']) > 0)) enable = false;
|
if (info.round && (info.round - (game.roundNumber - player.storage[skills2[i] + '_roundcount']) > 0)) enable = false;
|
||||||
if (player.storage[`temp_ban_${skills2[i]}`] === true) enable = false;
|
for (const item in player.storage) {
|
||||||
|
if (item.startsWith('temp_ban_')) {
|
||||||
|
if(player.storage[item] !== true) continue;
|
||||||
|
const skillName = item.slice(9);
|
||||||
|
if (lib.skill[skillName]) {
|
||||||
|
const skills=game.expandSkills([skillName]);
|
||||||
|
if(skills.includes(skills2[i])) {
|
||||||
|
enable = false; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (event.isMine() || !event._aiexclude.includes(skills2[i])) {
|
if (event.isMine() || !event._aiexclude.includes(skills2[i])) {
|
||||||
|
@ -7135,14 +7151,14 @@ export class Game extends Uninstantable {
|
||||||
event.avatars[i].classList.add('selecting');
|
event.avatars[i].classList.add('selecting');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let rand2 = [];
|
let rand = [];
|
||||||
for (let i = 0; i < event.config.width; i++) {
|
for (let i = 0; i < event.config.width; i++) {
|
||||||
for (let j = 0; j < event.config.width - i; j++) {
|
for (let j = 0; j < event.config.width - i; j++) {
|
||||||
rand2.push(i);
|
rand.push(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i = 0; i < event.config.num; i++) {
|
for (let i = 0; i < event.config.num; i++) {
|
||||||
let rand2 = rand2.randomGet();
|
let rand2 = rand.randomGet();
|
||||||
for (let j = 0; j < rand2.length; j++) {
|
for (let j = 0; j < rand2.length; j++) {
|
||||||
if (rand2[j] == rand2) {
|
if (rand2[j] == rand2) {
|
||||||
rand2.splice(j--, 1);
|
rand2.splice(j--, 1);
|
||||||
|
|
|
@ -814,6 +814,7 @@ export class Get extends Uninstantable {
|
||||||
"[object Object]": true,
|
"[object Object]": true,
|
||||||
"[object Array]": true,
|
"[object Array]": true,
|
||||||
"[object Arguments]": true,
|
"[object Arguments]": true,
|
||||||
|
"[object Date]": true
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof obj !== "object" || obj === null || !canTranverse[getType(obj)])
|
if (typeof obj !== "object" || obj === null || !canTranverse[getType(obj)])
|
||||||
|
@ -827,16 +828,22 @@ export class Get extends Uninstantable {
|
||||||
const target =
|
const target =
|
||||||
constructor
|
constructor
|
||||||
? (
|
? (
|
||||||
// 这三类数据处理单独处理
|
// 这四类数据处理单独处理
|
||||||
// (实际上需要处理的只有Map和Set)
|
// (实际上需要处理的只有Map和Set)
|
||||||
// 除此之外的就只能祝愿有拷贝构造函数了
|
// 除此之外的就只能祝愿有拷贝构造函数了
|
||||||
(Array.isArray(obj) || obj instanceof Map || obj instanceof Set)
|
(Array.isArray(obj) || obj instanceof Map || obj instanceof Set || constructor === Object)
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
? new constructor()
|
? new constructor()
|
||||||
// @ts-ignore
|
: (
|
||||||
: new constructor(obj)
|
(constructor.name in window && /\[native code\]/.test(constructor.toString()))
|
||||||
|
// @ts-ignore
|
||||||
|
? new constructor(obj)
|
||||||
|
: obj
|
||||||
|
)
|
||||||
)
|
)
|
||||||
: Object.create(null);
|
: Object.create(null);
|
||||||
|
if (target === obj) return target;
|
||||||
|
|
||||||
map.set(obj, target);
|
map.set(obj, target);
|
||||||
|
|
||||||
if (obj instanceof Map) {
|
if (obj instanceof Map) {
|
||||||
|
@ -1360,11 +1367,13 @@ export class Get extends Uninstantable {
|
||||||
}
|
}
|
||||||
static infoFuncOL(info) {
|
static infoFuncOL(info) {
|
||||||
var func;
|
var func;
|
||||||
|
const str = info.slice(13).trim();
|
||||||
try {
|
try {
|
||||||
eval('func=(' + info.slice(13) + ');');
|
if (str.startsWith("function") || str.startsWith("(")) eval(`func=(${str});`);
|
||||||
}
|
else eval(`func=(function ${str});`);
|
||||||
catch (e) {
|
} catch (e) {
|
||||||
return function () { };
|
console.error(`${e} in \n${str}`);
|
||||||
|
return function () {};
|
||||||
}
|
}
|
||||||
if (Array.isArray(func)) {
|
if (Array.isArray(func)) {
|
||||||
func = get.filter.apply(this, get.parsedResult(func));
|
func = get.filter.apply(this, get.parsedResult(func));
|
||||||
|
@ -1954,8 +1963,8 @@ export class Get extends Uninstantable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param { number | [number, number] | (()=>[number, number]) } [select]
|
* @param { number | Select | (()=>Select) } [select]
|
||||||
* @returns { [number, number] }
|
* @returns { Select }
|
||||||
*/
|
*/
|
||||||
static select(select) {
|
static select(select) {
|
||||||
if (typeof select == 'function') return get.select(select());
|
if (typeof select == 'function') return get.select(select());
|
||||||
|
@ -3007,7 +3016,16 @@ export class Get extends Uninstantable {
|
||||||
var js = node.getCards('j');
|
var js = node.getCards('j');
|
||||||
for (var i = 0; i < js.length; i++) {
|
for (var i = 0; i < js.length; i++) {
|
||||||
if (js[i].viewAs && js[i].viewAs != js[i].name) {
|
if (js[i].viewAs && js[i].viewAs != js[i].name) {
|
||||||
uiintro.add('<div><div class="skill">' + js[i].outerHTML + '</div><div>' + lib.translate[js[i].viewAs] + ':' + lib.translate[js[i].viewAs + '_info'] + '</div></div>');
|
let html = js[i].outerHTML;
|
||||||
|
let cardInfo = lib.card[js[i].viewAs], showCardIntro=true;
|
||||||
|
if (cardInfo.blankCard) {
|
||||||
|
var cardOwner = get.owner(js[i]);
|
||||||
|
if (cardOwner && !cardOwner.isUnderControl(true)) showCardIntro = false;
|
||||||
|
}
|
||||||
|
if (!showCardIntro) {
|
||||||
|
html=ui.create.button(js[i],'blank').outerHTML;
|
||||||
|
}
|
||||||
|
uiintro.add('<div><div class="skill">' + html + '</div><div>' + lib.translate[js[i].viewAs] + ':' + lib.translate[js[i].viewAs + '_info'] + '</div></div>');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uiintro.add('<div><div class="skill">' + js[i].outerHTML + '</div><div>' + lib.translate[js[i].name + '_info'] + '</div></div>');
|
uiintro.add('<div><div class="skill">' + js[i].outerHTML + '</div><div>' + lib.translate[js[i].name + '_info'] + '</div></div>');
|
||||||
|
@ -3477,7 +3495,7 @@ export class Get extends Uninstantable {
|
||||||
const defaultYingbianEffect = get.defaultYingbianEffect(node.link || node);
|
const defaultYingbianEffect = get.defaultYingbianEffect(node.link || node);
|
||||||
if (lib.yingbian.prompt.has(defaultYingbianEffect)) yingbianEffects.push(defaultYingbianEffect);
|
if (lib.yingbian.prompt.has(defaultYingbianEffect)) yingbianEffects.push(defaultYingbianEffect);
|
||||||
}
|
}
|
||||||
if (yingbianEffects.length) uiintro.add(`<div class="text" style="font-family: yuanli">应变:${yingbianEffects.map(value => lib.yingbian.prompt.get(value)).join(';')}</div>`);
|
if (yingbianEffects.length && showCardIntro) uiintro.add(`<div class="text" style="font-family: yuanli">应变:${yingbianEffects.map(value => lib.yingbian.prompt.get(value)).join(';')}</div>`);
|
||||||
}
|
}
|
||||||
if (lib.translate[name + '_append']) {
|
if (lib.translate[name + '_append']) {
|
||||||
uiintro.add('<div class="text" style="display:inline">' + lib.translate[name + '_append'] + '</div>');
|
uiintro.add('<div class="text" style="display:inline">' + lib.translate[name + '_append'] + '</div>');
|
||||||
|
|
|
@ -332,7 +332,7 @@ export class Is extends Uninstantable {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static altered() { return false; }
|
static altered(skillName) { return false; }
|
||||||
/*
|
/*
|
||||||
skill=>{
|
skill=>{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -17,7 +17,7 @@ export async function cordovaReady() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.addEventListener("resume", () => {
|
document.addEventListener("resume", () => {
|
||||||
if (ui.backgroundMusic) ui.backgroundMusic.play();
|
if (ui.backgroundMusic && !isNaN(ui.backgroundMusic.duration)) ui.backgroundMusic.play();
|
||||||
});
|
});
|
||||||
document.addEventListener("backbutton", function () {
|
document.addEventListener("backbutton", function () {
|
||||||
if (ui.arena && ui.arena.classList.contains('menupaused')) {
|
if (ui.arena && ui.arena.classList.contains('menupaused')) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Game as game } from '../game/index.js';
|
import { Game as game } from '../game/index.js';
|
||||||
|
import { lib } from '../library/index.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} name - 卡牌包名
|
* @param {string} name - 卡牌包名
|
||||||
|
@ -33,7 +34,20 @@ export const importMode = generateImportFunction('mode', (name) => `../../mode/$
|
||||||
*/
|
*/
|
||||||
function generateImportFunction(type, pathParser) {
|
function generateImportFunction(type, pathParser) {
|
||||||
return async (name) => {
|
return async (name) => {
|
||||||
const modeContent = await import(pathParser(name));
|
const path = pathParser(name);
|
||||||
|
// 通过浏览器自带的script标签导入可直接获取报错信息,且不会影响JS运行
|
||||||
|
// 此时代码内容也将缓存在浏览器中,故再次import后将不会重新执行代码内容(测试下来如此)
|
||||||
|
const [status, script] = await new Promise((resolve) => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.type = 'module';
|
||||||
|
script.src = `${lib.assetURL}noname/init/${path}`;
|
||||||
|
script.onerror = () => resolve(['error', script]);
|
||||||
|
script.onload = () => resolve(['ok', script]);
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
||||||
|
script.remove();
|
||||||
|
if (status === 'error') return;
|
||||||
|
const modeContent = await import(path);
|
||||||
if (!modeContent.type) return;
|
if (!modeContent.type) return;
|
||||||
if (modeContent.type !== type) throw new Error(`Loaded Content doesn't conform to "${type}" but "${modeContent.type}".`);
|
if (modeContent.type !== type) throw new Error(`Loaded Content doesn't conform to "${type}" but "${modeContent.type}".`);
|
||||||
await game.import(type, modeContent.default);
|
await game.import(type, modeContent.default);
|
||||||
|
|
|
@ -58,7 +58,7 @@ export async function boot() {
|
||||||
_status.event = lib.element.GameEvent.initialGameEvent();
|
_status.event = lib.element.GameEvent.initialGameEvent();
|
||||||
|
|
||||||
setWindowListener();
|
setWindowListener();
|
||||||
await setOnError();
|
const promiseErrorHandler = await setOnError();
|
||||||
|
|
||||||
// 无名杀更新日志
|
// 无名杀更新日志
|
||||||
if (window.noname_update) {
|
if (window.noname_update) {
|
||||||
|
@ -468,6 +468,7 @@ export async function boot() {
|
||||||
|
|
||||||
if (extensionlist.length && (config.get('mode') != 'connect' || show_splash)) {
|
if (extensionlist.length && (config.get('mode') != 'connect' || show_splash)) {
|
||||||
_status.extensionLoading = [];
|
_status.extensionLoading = [];
|
||||||
|
_status.extensionLoaded = [];
|
||||||
|
|
||||||
const bannedExtensions = Reflect.get(window, 'bannedExtensions');
|
const bannedExtensions = Reflect.get(window, 'bannedExtensions');
|
||||||
|
|
||||||
|
@ -477,8 +478,25 @@ export async function boot() {
|
||||||
extensionsLoading.push(importExtension(name));
|
extensionsLoading.push(importExtension(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.allSettled(extensionsLoading);
|
const extErrorList = [];
|
||||||
await Promise.allSettled(_status.extensionLoading);
|
for (const promise of extensionsLoading) {
|
||||||
|
await promise.catch(async (error) => {
|
||||||
|
extErrorList.add(error);
|
||||||
|
if (!promiseErrorHandler || !promiseErrorHandler.onHandle) return;
|
||||||
|
// @ts-ignore
|
||||||
|
await promiseErrorHandler.onHandle({ promise });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (const promise of _status.extensionLoading) {
|
||||||
|
await promise.catch(async (error) => {
|
||||||
|
if (extErrorList.includes(error)) return;
|
||||||
|
if (!promiseErrorHandler || !promiseErrorHandler.onHandle) return;
|
||||||
|
// @ts-ignore
|
||||||
|
await promiseErrorHandler.onHandle({ promise });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// await Promise.allSettled(_status.extensionLoading);
|
||||||
|
|
||||||
_status.extensionLoaded.filter(Boolean).forEach((name) => {
|
_status.extensionLoaded.filter(Boolean).forEach((name) => {
|
||||||
lib.announce.publish("Noname.Init.Extension.onLoad", name);
|
lib.announce.publish("Noname.Init.Extension.onLoad", name);
|
||||||
lib.announce.publish(`Noname.Init.Extension.${name}.onLoad`, void 0);
|
lib.announce.publish(`Noname.Init.Extension.${name}.onLoad`, void 0);
|
||||||
|
@ -843,7 +861,8 @@ async function setOnError() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//解析parsex里的content fun内容(通常是技能content)
|
//解析parsex里的content fun内容(通常是技能content)
|
||||||
else if (err && err.stack && err.stack.split('\n')[1].trim().startsWith('at Object.eval [as 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))) {
|
||||||
const codes = _status.event.content;
|
const codes = _status.event.content;
|
||||||
if (typeof codes == 'function') {
|
if (typeof codes == 'function') {
|
||||||
const lines = codes.toString().split("\n");
|
const lines = codes.toString().split("\n");
|
||||||
|
@ -867,6 +886,8 @@ async function setOnError() {
|
||||||
game.loop();
|
game.loop();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return promiseErrorHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setWindowListener() {
|
function setWindowListener() {
|
||||||
|
|
|
@ -393,6 +393,14 @@ export const Content = {
|
||||||
event.swapped = true;
|
event.swapped = true;
|
||||||
}
|
}
|
||||||
"step 5";
|
"step 5";
|
||||||
|
if (get.itemtype(result) == 'cards') {
|
||||||
|
for (let card of result){
|
||||||
|
if (card.willBeDestroyed('discardPile', player, event)) {
|
||||||
|
card.selfDestroy(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"step 6";
|
||||||
//if(player.isMin() || player.countCards('e',{subtype:get.subtype(card)})){
|
//if(player.isMin() || player.countCards('e',{subtype:get.subtype(card)})){
|
||||||
if (player.isMin() || !player.canEquip(card)) {
|
if (player.isMin() || !player.canEquip(card)) {
|
||||||
event.finish();
|
event.finish();
|
||||||
|
@ -411,7 +419,7 @@ export const Content = {
|
||||||
game.addVideo('equip', player, get.cardInfo(card));
|
game.addVideo('equip', player, get.cardInfo(card));
|
||||||
if (event.log != false) game.log(player, '装备了', card);
|
if (event.log != false) game.log(player, '装备了', card);
|
||||||
if (event.updatePile) game.updateRoundNumber();
|
if (event.updatePile) game.updateRoundNumber();
|
||||||
"step 6";
|
"step 7";
|
||||||
var info = get.info(card, false);
|
var info = get.info(card, false);
|
||||||
if (info.onEquip && (!info.filterEquip || info.filterEquip(card, player))) {
|
if (info.onEquip && (!info.filterEquip || info.filterEquip(card, player))) {
|
||||||
if (Array.isArray(info.onEquip)) {
|
if (Array.isArray(info.onEquip)) {
|
||||||
|
@ -476,6 +484,9 @@ export const Content = {
|
||||||
else black.push([target, card]);
|
else black.push([target, card]);
|
||||||
}
|
}
|
||||||
event.red = red; event.black = black;
|
event.red = red; event.black = black;
|
||||||
|
event.trigger('debateShowOpinion');
|
||||||
|
'step 2'
|
||||||
|
var red = event.red, black = event.black;
|
||||||
if (red.length) {
|
if (red.length) {
|
||||||
game.log(red.map(function (i) {
|
game.log(red.map(function (i) {
|
||||||
return i[0];
|
return i[0];
|
||||||
|
@ -528,7 +539,7 @@ export const Content = {
|
||||||
dialog.open();
|
dialog.open();
|
||||||
}, get.translation(player), event.videoId, red, black);
|
}, get.translation(player), event.videoId, red, black);
|
||||||
game.delay(4);
|
game.delay(4);
|
||||||
'step 2';
|
'step 3';
|
||||||
game.broadcastAll('closeDialog', event.videoId);
|
game.broadcastAll('closeDialog', event.videoId);
|
||||||
var opinion = null;
|
var opinion = null;
|
||||||
if (event.red.length > event.black.length) opinion = 'red';
|
if (event.red.length > event.black.length) opinion = 'red';
|
||||||
|
@ -542,7 +553,7 @@ export const Content = {
|
||||||
black: event.black,
|
black: event.black,
|
||||||
targets: event.targets
|
targets: event.targets
|
||||||
};
|
};
|
||||||
'step 3';
|
'step 4';
|
||||||
if (event.callback) {
|
if (event.callback) {
|
||||||
var next = game.createEvent('debateCallback', false);
|
var next = game.createEvent('debateCallback', false);
|
||||||
next.player = player;
|
next.player = player;
|
||||||
|
@ -1999,47 +2010,57 @@ export const Content = {
|
||||||
event.callback();
|
event.callback();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
arrangeTrigger: function () {
|
arrangeTrigger: async function (event,trigger,player) {
|
||||||
'step 0';
|
while(event.doingList.length>0){
|
||||||
event.doing = event.doingList[0];
|
event.doing = event.doingList.shift();
|
||||||
if (event.doing && event.doing.todoList.length) return;
|
while(true){
|
||||||
if (event.doingList.length) {
|
if (trigger.filterStop && trigger.filterStop()) return;
|
||||||
event.doingList.shift();
|
const usableSkills = event.doing.todoList.filter(info => {
|
||||||
return event.redo();
|
if (!lib.filter.filterTrigger(trigger, info.player, event.triggername, info.skill)) return false;
|
||||||
|
return lib.skill.global.includes(info.skill) || info.player.hasSkill(info.skill, true);
|
||||||
|
});
|
||||||
|
if (usableSkills.length == 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
event.doing.todoList = event.doing.todoList.filter(i => i.priority <= usableSkills[0].priority);
|
||||||
|
//firstDo时机和lastDo时机不进行技能优先级选择
|
||||||
|
if (get.itemtype(event.doing.player) !== 'player'){
|
||||||
|
event.current = usableSkills[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
event.choice = usableSkills.filter(n => n.priority == usableSkills[0].priority);
|
||||||
|
//现在只要找到一个同优先度技能为silent 便优先执行该技能
|
||||||
|
const silentSkill = event.choice.find(item => {
|
||||||
|
const skillInfo = lib.skill[item.skill];
|
||||||
|
return (skillInfo && skillInfo.silent);
|
||||||
|
})
|
||||||
|
if (silentSkill){
|
||||||
|
event.current = silentSkill;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const currentChoice = event.choice[0];
|
||||||
|
if (event.choice.length == 1) {
|
||||||
|
event.current = currentChoice;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
const currentPlayer = currentChoice.player , skillsToChoose = event.choice.map(i => i.skill);
|
||||||
|
const next = currentPlayer.chooseControl(skillsToChoose);
|
||||||
|
next.set('prompt', '选择下一个触发的技能');
|
||||||
|
next.set('forceDie', true);
|
||||||
|
next.set('arrangeSkill', true);
|
||||||
|
next.set('includeOut', true);
|
||||||
|
const {result} = await next;
|
||||||
|
event.current = event.doing.todoList.find(info => info.skill == result.control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event.doing.doneList.push(event.current);
|
||||||
|
event.doing.todoList.remove(event.current);
|
||||||
|
await game.createTrigger(event.triggername, event.current.skill, event.current.player, trigger);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
event.finish();
|
|
||||||
'step 1';
|
|
||||||
if (trigger.filterStop && trigger.filterStop()) return event.finish();
|
|
||||||
event.current = event.doing.todoList.find(info => lib.filter.filterTrigger(trigger, info.player, event.triggername, info.skill));
|
|
||||||
if (!event.current) {
|
|
||||||
event.doing.todoList = [];
|
|
||||||
return event.goto(0);
|
|
||||||
}
|
|
||||||
event.doing.todoList = event.doing.todoList.filter(i => i.priority <= event.current.priority);
|
|
||||||
|
|
||||||
const directUse = info => lib.skill[info.skill].silent || !lib.translate[info.skill];//是否不触发同顺序选择
|
|
||||||
if (directUse(event.current)) return event.goto(4);
|
|
||||||
event.choice = event.doing.todoList.filter(info => {
|
|
||||||
if (!lib.filter.filterTrigger(trigger, info.player, event.triggername, info.skill)) return false;
|
|
||||||
if (directUse(info)) return false;
|
|
||||||
if (event.current.player !== info.player) return false;
|
|
||||||
return lib.skill.global.includes(info.skill) || event.current.player.hasSkill(info.skill, true);
|
|
||||||
});
|
|
||||||
if (event.choice.length < 2) return event.goto(4);
|
|
||||||
'step 2';
|
|
||||||
const next = event.choice[0].player.chooseControl(event.choice.map(i => i.skill));
|
|
||||||
next.set('prompt', '选择下一个触发的技能');
|
|
||||||
next.set('forceDie', true);
|
|
||||||
next.set('arrangeSkill', true);
|
|
||||||
next.set('includeOut', true);
|
|
||||||
'step 3';
|
|
||||||
if (result.control) event.current = event.doing.todoList.find(info => info.skill == result.control && info.player == event.choice[0].player);
|
|
||||||
'step 4';
|
|
||||||
if (!event.current || !event.doing.todoList.includes(event.current)) return;
|
|
||||||
event.doing.doneList.push(event.current);
|
|
||||||
event.doing.todoList.remove(event.current);
|
|
||||||
game.createTrigger(event.triggername, event.current.skill, event.current.player, trigger);
|
|
||||||
event.goto(0);
|
|
||||||
},
|
},
|
||||||
createTrigger: function () {
|
createTrigger: function () {
|
||||||
"step 0";
|
"step 0";
|
||||||
|
@ -2143,11 +2164,11 @@ export const Content = {
|
||||||
next._trigger = trigger;
|
next._trigger = trigger;
|
||||||
next.triggername = event.triggername;
|
next.triggername = event.triggername;
|
||||||
|
|
||||||
if ("contents" in info && Array.isArray(info.contents)) {
|
// if ("contents" in info && Array.isArray(info.contents)) {
|
||||||
next.setContents(info.contents);
|
// next.setContents(info.contents);
|
||||||
} else {
|
// } else {
|
||||||
next.setContent(info.content);
|
next.setContent(info.content);
|
||||||
}
|
// }
|
||||||
|
|
||||||
next.skillHidden = event.skillHidden;
|
next.skillHidden = event.skillHidden;
|
||||||
if (info.forceDie) next.forceDie = true;
|
if (info.forceDie) next.forceDie = true;
|
||||||
|
@ -8163,7 +8184,12 @@ export const Content = {
|
||||||
cards[0].classList.add('fakejudge');
|
cards[0].classList.add('fakejudge');
|
||||||
cards[0].node.background.innerHTML = lib.translate[cards[0].viewAs + '_bg'] || get.translation(cards[0].viewAs)[0];
|
cards[0].node.background.innerHTML = lib.translate[cards[0].viewAs + '_bg'] || get.translation(cards[0].viewAs)[0];
|
||||||
}
|
}
|
||||||
game.log(player, '被贴上了<span class="yellowtext">' + get.translation(cards[0].viewAs) + '</span>(', cards, ')');
|
if(lib.card[viewAs].blankCard){
|
||||||
|
game.log(player, '被扣置了<span class="yellowtext">' + get.translation(cards[0].viewAs) + '</span>');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
game.log(player, '被贴上了<span class="yellowtext">' + get.translation(cards[0].viewAs) + '</span>(', cards, ')');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cards[0].classList.remove('fakejudge');
|
cards[0].classList.remove('fakejudge');
|
||||||
|
|
|
@ -45,6 +45,10 @@ export class GameEvent {
|
||||||
};
|
};
|
||||||
this._aiexclude = [];
|
this._aiexclude = [];
|
||||||
this._notrigger = [];
|
this._notrigger = [];
|
||||||
|
/**
|
||||||
|
* @type { Result }
|
||||||
|
*/
|
||||||
|
// @ts-ignore
|
||||||
this._result = {};
|
this._result = {};
|
||||||
this._set = [];
|
this._set = [];
|
||||||
/**
|
/**
|
||||||
|
@ -738,7 +742,7 @@ export class GameEvent {
|
||||||
untrigger(all = true, player) {
|
untrigger(all = true, player) {
|
||||||
const evt = this._triggering;
|
const evt = this._triggering;
|
||||||
if (all) {
|
if (all) {
|
||||||
this._triggered = 5;
|
if(all !== 'currentOnly') this._triggered = 5;
|
||||||
if (evt && evt.doingList) {
|
if (evt && evt.doingList) {
|
||||||
evt.doingList.forEach(doing => doing.todoList = []);
|
evt.doingList.forEach(doing => doing.todoList = []);
|
||||||
}
|
}
|
||||||
|
@ -749,11 +753,6 @@ export class GameEvent {
|
||||||
// const doing=evt.doingList.find(doing=>doing.player==player);
|
// const doing=evt.doingList.find(doing=>doing.player==player);
|
||||||
// if(doing) doing.todoList=[];
|
// if(doing) doing.todoList=[];
|
||||||
}
|
}
|
||||||
else if (all==='currentOnly'){
|
|
||||||
if (evt && evt.doingList) {
|
|
||||||
evt.doingList.forEach(doing => doing.todoList = []);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -862,6 +861,11 @@ export class GameEvent {
|
||||||
*/
|
*/
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.excludeButton;
|
this.excludeButton;
|
||||||
|
/**
|
||||||
|
* @type { Result }
|
||||||
|
*/
|
||||||
|
// @ts-ignore
|
||||||
|
this.result;
|
||||||
throw new Error('Do not call this method');
|
throw new Error('Do not call this method');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { AsyncFunction } from '../../util/index.js';
|
||||||
* 且Promise的原有属性无法被修改,一切对这个类实例的属性修改,删除,
|
* 且Promise的原有属性无法被修改,一切对这个类实例的属性修改,删除,
|
||||||
* 再配置等操作都会转发到事件对应的属性中。
|
* 再配置等操作都会转发到事件对应的属性中。
|
||||||
*
|
*
|
||||||
* @todo 需要完成异步事件的debugger方法
|
* @template { GameEvent } T
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* 使用await xx()等待异步事件执行:
|
* 使用await xx()等待异步事件执行:
|
||||||
|
|
|
@ -1,132 +1,125 @@
|
||||||
import { AI as ai } from '../../ai/index.js';
|
import { AI as ai } from '../../ai/index.js';
|
||||||
import { Get as get } from '../../get/index.js';
|
import { Get as get } from '../../get/index.js';
|
||||||
import { Game as game } from '../../game/index.js';
|
import { Game as game } from '../../game/index.js';
|
||||||
import { Library as lib } from "../index.js";
|
import { Library as lib } from "../index.js";
|
||||||
import { status as _status } from '../../status/index.js';
|
import { status as _status } from '../../status/index.js';
|
||||||
import { UI as ui } from '../../ui/index.js';
|
import { UI as ui } from '../../ui/index.js';
|
||||||
|
|
||||||
export class VCard {
|
export class VCard {
|
||||||
/**
|
/**
|
||||||
* @param { any } [suitOrCard]
|
* @param { any } [suitOrCard]
|
||||||
* @param { number | Card[] } [numberOrCards]
|
* @param { number | Card[] } [numberOrCards]
|
||||||
* @param { string } [name]
|
* @param { string } [name]
|
||||||
* @param { string } [nature]
|
* @param { string } [nature]
|
||||||
*/
|
*/
|
||||||
constructor(suitOrCard, numberOrCards, name, nature) {
|
constructor(suitOrCard, numberOrCards, name, nature) {
|
||||||
if (suitOrCard instanceof VCard) {
|
if (Array.isArray(suitOrCard)) {
|
||||||
const other = suitOrCard;
|
/**
|
||||||
[suitOrCard, numberOrCards, name, nature] = other._args;
|
* @type {string}
|
||||||
}
|
*/
|
||||||
|
this.suit = suitOrCard[0];
|
||||||
if (Array.isArray(suitOrCard)) {
|
/**
|
||||||
/**
|
* @type {number}
|
||||||
* @type {string}
|
*/
|
||||||
*/
|
this.number = suitOrCard[1];
|
||||||
this.suit = suitOrCard[0];
|
/**
|
||||||
/**
|
* @type {string}
|
||||||
* @type {number}
|
*/
|
||||||
*/
|
this.name = suitOrCard[2];
|
||||||
this.number = suitOrCard[1];
|
/**
|
||||||
/**
|
* @type {string}
|
||||||
* @type {string}
|
*/
|
||||||
*/
|
this.nature = suitOrCard[3];
|
||||||
this.name = suitOrCard[2];
|
}
|
||||||
/**
|
// @ts-ignore
|
||||||
* @type {string}
|
else if (get.itemtype(suitOrCard) == 'card') {
|
||||||
*/
|
this.name = get.name(suitOrCard);
|
||||||
this.nature = suitOrCard[3];
|
this.suit = get.suit(suitOrCard);
|
||||||
}
|
this.color = get.color(suitOrCard);
|
||||||
// @ts-ignore
|
this.number = get.number(suitOrCard);
|
||||||
else if (get.itemtype(suitOrCard) == 'card') {
|
this.nature = get.nature(suitOrCard);
|
||||||
this.name = get.name(suitOrCard);
|
/**
|
||||||
this.suit = get.suit(suitOrCard);
|
* @type { boolean }
|
||||||
this.color = get.color(suitOrCard);
|
*/
|
||||||
this.number = get.number(suitOrCard);
|
this.isCard = true;
|
||||||
this.nature = get.nature(suitOrCard);
|
this.cardid = suitOrCard.cardid;
|
||||||
/**
|
this.wunature = suitOrCard.wunature;
|
||||||
* @type { boolean }
|
/**
|
||||||
*/
|
* @type {Record<string, any>}
|
||||||
this.isCard = true;
|
*/
|
||||||
this.cardid = suitOrCard.cardid;
|
this.storage = get.copy(suitOrCard.storage);
|
||||||
this.wunature = suitOrCard.wunature;
|
if (Array.isArray(numberOrCards)) this.cards = numberOrCards.slice();
|
||||||
/**
|
else this.cards = [suitOrCard];
|
||||||
* @type {Record<string, any>}
|
const info = get.info(this, false);
|
||||||
*/
|
if (info) {
|
||||||
this.storage = get.copy(suitOrCard.storage);
|
const autoViewAs = info.autoViewAs;
|
||||||
if (Array.isArray(numberOrCards)) this.cards = numberOrCards.slice();
|
if (typeof autoViewAs == 'string') this.name = autoViewAs;
|
||||||
else this.cards = [suitOrCard];
|
}
|
||||||
const info = get.info(this, false);
|
}
|
||||||
if (info) {
|
else if (suitOrCard && typeof suitOrCard != 'string') {
|
||||||
const autoViewAs = info.autoViewAs;
|
Object.keys(suitOrCard).forEach(key => {
|
||||||
if (typeof autoViewAs == 'string') this.name = autoViewAs;
|
/**
|
||||||
}
|
* @type { PropertyDescriptor }
|
||||||
}
|
*/
|
||||||
else if (suitOrCard && typeof suitOrCard != 'string') {
|
// @ts-ignore
|
||||||
Object.keys(suitOrCard).forEach(key => {
|
const propertyDescriptor = Object.getOwnPropertyDescriptor(suitOrCard, key), value = propertyDescriptor.value;
|
||||||
/**
|
if (Array.isArray(value)) this[key] = value.slice();
|
||||||
* @type { PropertyDescriptor }
|
else Object.defineProperty(this, key, propertyDescriptor);
|
||||||
*/
|
});
|
||||||
// @ts-ignore
|
if (Array.isArray(numberOrCards)) {
|
||||||
const propertyDescriptor = Object.getOwnPropertyDescriptor(suitOrCard, key), value = propertyDescriptor.value;
|
const noCards = !this.cards;
|
||||||
if (Array.isArray(value)) this[key] = value.slice();
|
/**
|
||||||
else Object.defineProperty(this, key, propertyDescriptor);
|
* @type { Card[] }
|
||||||
});
|
*/
|
||||||
if (Array.isArray(numberOrCards)) {
|
this.cards = numberOrCards.slice();
|
||||||
const noCards = !this.cards;
|
if (noCards) {
|
||||||
/**
|
if (!lib.suits.includes(this.suit)) this.suit = get.suit(this);
|
||||||
* @type { Card[] }
|
if (!Object.keys(lib.color).includes(this.color)) this.color = get.color(this);
|
||||||
*/
|
if (typeof this.number != 'number') this.number = get.number(this);
|
||||||
this.cards = numberOrCards.slice();
|
if (!this.nature) this.nature = get.nature(this);
|
||||||
if (noCards) {
|
}
|
||||||
if (!lib.suits.includes(this.suit)) this.suit = get.suit(this);
|
}
|
||||||
if (!Object.keys(lib.color).includes(this.color)) this.color = get.color(this);
|
const info = get.info(this, false);
|
||||||
if (typeof this.number != 'number') this.number = get.number(this);
|
if (info) {
|
||||||
if (!this.nature) this.nature = get.nature(this);
|
const autoViewAs = info.autoViewAs;
|
||||||
}
|
if (typeof autoViewAs == 'string') this.name = autoViewAs;
|
||||||
}
|
}
|
||||||
const info = get.info(this, false);
|
}
|
||||||
if (info) {
|
if (typeof suitOrCard == 'string') this.suit = suitOrCard;
|
||||||
const autoViewAs = info.autoViewAs;
|
if (typeof numberOrCards == 'number') this.number = numberOrCards;
|
||||||
if (typeof autoViewAs == 'string') this.name = autoViewAs;
|
if (typeof name == 'string') this.name = name;
|
||||||
}
|
if (typeof nature == 'string') this.nature = nature;
|
||||||
}
|
if (!this.storage) this.storage = {};
|
||||||
if (typeof suitOrCard == 'string') this.suit = suitOrCard;
|
if (!this.cards) this.cards = [];
|
||||||
if (typeof numberOrCards == 'number') this.number = numberOrCards;
|
}
|
||||||
if (typeof name == 'string') this.name = name;
|
sameSuitAs(card) {
|
||||||
if (typeof nature == 'string') this.nature = nature;
|
return get.suit(this) == get.suit(card);
|
||||||
if (!this.storage) this.storage = {};
|
}
|
||||||
if (!this.cards) this.cards = [];
|
differentSuitFrom(card) {
|
||||||
|
return get.suit(this) != get.suit(card);
|
||||||
this._args = [suitOrCard, numberOrCards, name, nature];
|
}
|
||||||
}
|
sameNumberAs(card) {
|
||||||
sameSuitAs(card) {
|
return get.number(this) == get.number(card);
|
||||||
return get.suit(this) == get.suit(card);
|
}
|
||||||
}
|
differentNumberFrom(card) {
|
||||||
differentSuitFrom(card) {
|
return get.number(this) != get.number(card);
|
||||||
return get.suit(this) != get.suit(card);
|
}
|
||||||
}
|
sameNameAs(card) {
|
||||||
sameNumberAs(card) {
|
return get.name(this) == get.name(card);
|
||||||
return get.number(this) == get.number(card);
|
}
|
||||||
}
|
differentNameFrom(card) {
|
||||||
differentNumberFrom(card) {
|
return get.name(this) != get.name(card);
|
||||||
return get.number(this) != get.number(card);
|
}
|
||||||
}
|
/**
|
||||||
sameNameAs(card) {
|
* @param { Player } player
|
||||||
return get.name(this) == get.name(card);
|
*/
|
||||||
}
|
hasNature(nature, player) {
|
||||||
differentNameFrom(card) {
|
const natures = get.natureList(this, player);
|
||||||
return get.name(this) != get.name(card);
|
if (!nature) return natures.length > 0;
|
||||||
}
|
if (nature == 'linked') return natures.some(n => lib.linked.includes(n));
|
||||||
/**
|
return get.is.sameNature(natures, nature);
|
||||||
* @param { Player } player
|
}
|
||||||
*/
|
hasGaintag(tag) {
|
||||||
hasNature(nature, player) {
|
return this.gaintag && this.gaintag.includes(tag);
|
||||||
const natures = get.natureList(this, player);
|
}
|
||||||
if (!nature) return natures.length > 0;
|
}
|
||||||
if (nature == 'linked') return natures.some(n => lib.linked.includes(n));
|
|
||||||
return get.is.sameNature(natures, nature);
|
|
||||||
}
|
|
||||||
hasGaintag(tag) {
|
|
||||||
return this.gaintag && this.gaintag.includes(tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
26217
noname/library/index.js
|
@ -4190,7 +4190,7 @@ class Create extends Uninstantable {
|
||||||
}
|
}
|
||||||
editnode.classList.remove('disabled');
|
editnode.classList.remove('disabled');
|
||||||
};
|
};
|
||||||
var clickButton = async () => {
|
var clickButton = async function () {
|
||||||
if (currentButton == this) {
|
if (currentButton == this) {
|
||||||
resetEditor();
|
resetEditor();
|
||||||
return;
|
return;
|
||||||
|
@ -8652,6 +8652,48 @@ class Create extends Uninstantable {
|
||||||
clickCapt.call(node[lib.config.character_dialog_tool]);
|
clickCapt.call(node[lib.config.character_dialog_tool]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//仅仅下面是新加的,by Curpond
|
||||||
|
|
||||||
|
let container = dialog.querySelector('.content-container>.content')
|
||||||
|
let Searcher = ui.create.div('.searcher.caption')
|
||||||
|
let input = document.createElement('input')
|
||||||
|
input.style.textAlign = 'center'
|
||||||
|
input.style.border = 'solid 2px #294510'
|
||||||
|
input.style.borderRadius = '6px'
|
||||||
|
input.style.fontWeight = 'bold'
|
||||||
|
input.style.fontSize = '21px'
|
||||||
|
let find = ui.create.button(['find', '搜索'], 'tdnodes')
|
||||||
|
find.style.display = 'inline'
|
||||||
|
let clickfind = function (e) {
|
||||||
|
e.stopPropagation()
|
||||||
|
let value = input.value
|
||||||
|
if (value == '') {
|
||||||
|
game.alert('搜索不能为空')
|
||||||
|
input.focus()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let list = []
|
||||||
|
for (let btn of dialog.buttons) {
|
||||||
|
|
||||||
|
if ((new RegExp(value, 'g').test(get.translation(btn.link)))) {
|
||||||
|
btn.classList.remove('nodisplay')
|
||||||
|
} else {
|
||||||
|
btn.classList.add('nodisplay')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
input.addEventListener('keyup', (e) => {
|
||||||
|
|
||||||
|
if (e.key == 'Enter') clickfind(e)
|
||||||
|
})
|
||||||
|
find.listen(clickfind)
|
||||||
|
Searcher.appendChild(input)
|
||||||
|
Searcher.appendChild(find)
|
||||||
|
container.prepend(Searcher)
|
||||||
|
|
||||||
|
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
static dialog() {
|
static dialog() {
|
||||||
|
@ -9008,10 +9050,9 @@ class Create extends Uninstantable {
|
||||||
ui.backgroundMusic.autoplay = true;
|
ui.backgroundMusic.autoplay = true;
|
||||||
ui.backgroundMusic.addEventListener('ended', game.playBackgroundMusic);
|
ui.backgroundMusic.addEventListener('ended', game.playBackgroundMusic);
|
||||||
ui.window.appendChild(ui.backgroundMusic);
|
ui.window.appendChild(ui.backgroundMusic);
|
||||||
ui.window.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', function playMusic() {
|
ui.window.addEventListener(lib.config.touchscreen ? 'touchend' : 'click', () => {
|
||||||
ui.window.removeEventListener(lib.config.touchscreen ? 'touchend' : 'click', playMusic, false);
|
if (!ui.backgroundMusic.played.length && lib.config.background_music != 'music_off' && !isNaN(ui.backgroundMusic.duration)) ui.backgroundMusic.play();
|
||||||
if (!ui.backgroundMusic.played.length && lib.config.background_music != 'music_off') ui.backgroundMusic.play();
|
}, {once:true});
|
||||||
}, false);
|
|
||||||
if (lib.config.cursor_style == 'pointer') {
|
if (lib.config.cursor_style == 'pointer') {
|
||||||
ui.window.classList.add('nopointer');
|
ui.window.classList.add('nopointer');
|
||||||
}
|
}
|
||||||
|
@ -9624,8 +9665,8 @@ class Create extends Uninstantable {
|
||||||
if (get.position(item) == 'j' && item.viewAs && lib.config.cardtempname != 'off') {
|
if (get.position(item) == 'j' && item.viewAs && lib.config.cardtempname != 'off') {
|
||||||
node.classList.add('infoflip');
|
node.classList.add('infoflip');
|
||||||
node.classList.add('infohidden')
|
node.classList.add('infohidden')
|
||||||
ui.create.cardTempName(item, node).style.setProperty('display','block','important')
|
ui.create.cardTempName(item, node).style.setProperty('display', 'block', 'important')
|
||||||
|
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
|
@ -13377,12 +13418,14 @@ class Click extends Uninstantable {
|
||||||
// 有bug,先用旧版
|
// 有bug,先用旧版
|
||||||
if (lib.config.background_speak && e !== 'init') {
|
if (lib.config.background_speak && e !== 'init') {
|
||||||
let audio, skillnode = this;
|
let audio, skillnode = this;
|
||||||
|
const playedAudios = [];
|
||||||
(function play() {
|
(function play() {
|
||||||
if (!skillnode.audioList || !skillnode.audioList.length) {
|
if (!skillnode.audioList || !skillnode.audioList.length) {
|
||||||
skillnode.audioList = game.parseSkillAudio(skillnode.link, playername);
|
skillnode.audioList = game.parseSkillAudio(skillnode.link, playername);
|
||||||
if (!skillnode.audioList.length) return;
|
if (!skillnode.audioList.length||skillnode.audioList.length==playedAudios.length) return;
|
||||||
}
|
}
|
||||||
audio = skillnode.audioList.shift();
|
audio = skillnode.audioList.shift();
|
||||||
|
playedAudios.push(audio);
|
||||||
game.playAudio(audio, play);
|
game.playAudio(audio, play);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
@ -13592,12 +13635,14 @@ class Click extends Uninstantable {
|
||||||
// 有bug,先用旧版
|
// 有bug,先用旧版
|
||||||
if (lib.config.background_speak && e !== 'init') {
|
if (lib.config.background_speak && e !== 'init') {
|
||||||
let audio, skillnode = this;
|
let audio, skillnode = this;
|
||||||
|
const playedAudios = [];
|
||||||
(function play() {
|
(function play() {
|
||||||
if (!skillnode.audioList || !skillnode.audioList.length) {
|
if (!skillnode.audioList || !skillnode.audioList.length) {
|
||||||
skillnode.audioList = game.parseSkillAudio(skillnode.link, playername);
|
skillnode.audioList = game.parseSkillAudio(skillnode.link, playername);
|
||||||
if (!skillnode.audioList.length) return;
|
if (!skillnode.audioList.length||skillnode.audioList.length==playedAudios.length) return;
|
||||||
}
|
}
|
||||||
audio = skillnode.audioList.shift();
|
audio = skillnode.audioList.shift();
|
||||||
|
playedAudios.push(audio);
|
||||||
game.playAudio(audio, play);
|
game.playAudio(audio, play);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
@ -14092,6 +14137,18 @@ export class UI extends Uninstantable {
|
||||||
* @type { Control | undefined }
|
* @type { Control | undefined }
|
||||||
*/
|
*/
|
||||||
static skills3;
|
static skills3;
|
||||||
|
/**
|
||||||
|
* @type { HTMLDivElement }
|
||||||
|
*/
|
||||||
|
static window;
|
||||||
|
/**
|
||||||
|
* @type { HTMLDivElement }
|
||||||
|
*/
|
||||||
|
static pause;
|
||||||
|
/**
|
||||||
|
* @type { HTMLAudioElement }
|
||||||
|
*/
|
||||||
|
static backgroundMusic;
|
||||||
static refresh(node) {
|
static refresh(node) {
|
||||||
void window.getComputedStyle(node, null).getPropertyValue("opacity");
|
void window.getComputedStyle(node, null).getPropertyValue("opacity");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,49 @@
|
||||||
/**
|
/**
|
||||||
* 关于`Google Chrome`的异步错误处理
|
* 关于`Google Chrome`的异步错误处理
|
||||||
*
|
*
|
||||||
* `Chrome`所用的`v8`引擎为`Error`提供了特有的报错栈堆处理函数,用于用户自定义报错栈堆的内容。
|
* 由于`v8`提供的`Error.prepareStackTrace(error, structuredStackTrace)`接口存在一些限制,导致不适合无名杀
|
||||||
*
|
*
|
||||||
* 我们用到了`Error.prepareStackTrace(error, structuredStackTrace)`这个函数,这个函数的信息可参考[这里](https://v8.dev/docs/stack-trace-api#customizing-stack-traces)
|
* 故我们直接解析`Error`的栈堆信息,来获取相关内容
|
||||||
*
|
*
|
||||||
* 该函数提供了结构化的栈堆信息,很幸运的是,这个结构化的栈堆能直接告诉我们报错的文件以及位置,故我们使用该函数,让异步报错能直接定位原始位置
|
* ~~`Chrome`所用的`v8`引擎为`Error`提供了特有的报错栈堆处理接口,用于用户自定义报错栈堆的内容。~~
|
||||||
|
*
|
||||||
|
* ~~我们用到了`Error.prepareStackTrace(error, structuredStackTrace)`这个接口,这个接口的信息可参考[这里](https://v8.dev/docs/stack-trace-api#customizing-stack-traces)~~
|
||||||
|
*
|
||||||
|
* ~~该接口提供了结构化的栈堆信息,很幸运的是,这个结构化的栈堆能直接告诉我们报错的文件以及位置,故我们使用该接口,让异步报错能直接定位原始位置~~
|
||||||
*
|
*
|
||||||
* @implements {PromiseErrorHandler}
|
* @implements {PromiseErrorHandler}
|
||||||
*/
|
*/
|
||||||
export class ChromePromiseErrorHandler {
|
export class ChromePromiseErrorHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于临时记录报错信息的列表,通过`Error.prepareStackTrace`更新该列表
|
* ~~用于临时记录报错信息的列表,通过`Error.prepareStackTrace`更新该列表~~
|
||||||
*
|
*
|
||||||
* @type {[Error, NodeJS.CallSite[]][]}
|
* 现在用于存储报错过的错误信息
|
||||||
|
*
|
||||||
|
* @type {Error[]}
|
||||||
*/
|
*/
|
||||||
#errorList;
|
#errorList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {typeof Error.prepareStackTrace}
|
* @type {typeof Error.prepareStackTrace}
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
#originErrorPrepareStackTrace;
|
#_originErrorPrepareStackTrace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化`Error.prepareStackTrace`,将该值赋值成我们需要的函数
|
* 判断是否是v8错误栈堆用到的正则
|
||||||
|
*/
|
||||||
|
#STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ~~初始化`Error.prepareStackTrace`,将该值赋值成我们需要的函数~~
|
||||||
*
|
*
|
||||||
* 未防止本来Error.prepareStackTrace便存在赋值的行为,我们将原始值存储,并在需要的函数中调用
|
* ~~未防止本来Error.prepareStackTrace便存在赋值的行为,我们将原始值存储,并在需要的函数中调用~~
|
||||||
*
|
*
|
||||||
* > 这或许就是本体扩展化的第一步(小声)
|
* 初始化存储报错信息的列表
|
||||||
*/
|
*/
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
/*
|
||||||
this.#errorList = [];
|
this.#errorList = [];
|
||||||
this.#originErrorPrepareStackTrace = Error.prepareStackTrace;
|
this.#originErrorPrepareStackTrace = Error.prepareStackTrace;
|
||||||
Error.prepareStackTrace = (error, stackTraces) => {
|
Error.prepareStackTrace = (error, stackTraces) => {
|
||||||
|
@ -42,13 +55,19 @@ export class ChromePromiseErrorHandler {
|
||||||
this.#errorList.push([error, stackTraces]);
|
this.#errorList.push([error, stackTraces]);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
this.#errorList = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将原来可能的`Error.prepareStackTrace`赋值回去
|
* ~~将原来可能的`Error.prepareStackTrace`赋值回去~~
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
onUnload() {
|
onUnload() {
|
||||||
|
/*
|
||||||
Error.prepareStackTrace = this.#originErrorPrepareStackTrace;
|
Error.prepareStackTrace = this.#originErrorPrepareStackTrace;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,6 +79,66 @@ export class ChromePromiseErrorHandler {
|
||||||
*/
|
*/
|
||||||
onHandle(event) {
|
onHandle(event) {
|
||||||
event.promise.catch((error) => {
|
event.promise.catch((error) => {
|
||||||
|
// 如果`error`是个错误,则继续处理
|
||||||
|
if (error instanceof Error) {
|
||||||
|
// 如果已经处理过该错误,则不再处理
|
||||||
|
if (this.#errorList.includes(error)) return;
|
||||||
|
this.#errorList.push(error);
|
||||||
|
// 如果`error`拥有字符串形式的报错栈堆,且报错栈堆确实符合v8的stack
|
||||||
|
if (typeof error.stack === 'string' && this.#STACK_REGEXP.test(error.stack)) {
|
||||||
|
// 获取符合栈堆信息的字符串,一般来说就是从第二行开始的所有行
|
||||||
|
// 为了处理eval的情况,故必须获取完行数
|
||||||
|
let lines = error.stack.split('\n').filter((line) =>
|
||||||
|
this.#STACK_REGEXP.test(line));
|
||||||
|
|
||||||
|
// 提供类型信息防止vscode报错
|
||||||
|
/**
|
||||||
|
* @type {string | undefined}
|
||||||
|
*/
|
||||||
|
let fileName = void 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number | undefined}
|
||||||
|
*/
|
||||||
|
let line = void 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number | undefined}
|
||||||
|
*/
|
||||||
|
let column = void 0;
|
||||||
|
|
||||||
|
// 从第一条开始遍历,一直遍历到不存在eval的位置
|
||||||
|
for (let currentLine = 0; currentLine < lines.length; ++currentLine) {
|
||||||
|
if (/\(eval /.test(lines[currentLine])) continue;
|
||||||
|
|
||||||
|
let formatedLine = lines[currentLine].replace(/^\s+/, '').replace(/\(eval code/g, '(').replace(/^.*?\s+/, '');
|
||||||
|
|
||||||
|
const location = formatedLine.match(/ (\(.+\)$)/);
|
||||||
|
if (location) formatedLine = formatedLine.replace(location[0], '');
|
||||||
|
|
||||||
|
const locationParts = extractLocation(location ? location[1] : formatedLine);
|
||||||
|
|
||||||
|
fileName = ['eval', '<anonymous>'].includes(locationParts[0]) ? void 0 : locationParts[0];
|
||||||
|
line = Number(locationParts[1]);
|
||||||
|
column = Number(locationParts[2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
window.onerror(error.message, fileName, line, column, error);
|
||||||
|
}
|
||||||
|
// 反之我们只能不考虑报错文件信息,直接调用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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
console.error(error)
|
||||||
const result = this.#errorList.find(savedError => savedError[0] === error);
|
const result = this.#errorList.find(savedError => savedError[0] === error);
|
||||||
if (result) {
|
if (result) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -71,17 +150,42 @@ export class ChromePromiseErrorHandler {
|
||||||
result[0]
|
result[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 正式报错时便不再需要报错信息了,故直接清空列表,释放内存
|
* ~~正式报错时便不再需要报错信息了,故直接清空列表,释放内存~~
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
onErrorPrepare() {
|
onErrorPrepare() {
|
||||||
|
/*
|
||||||
this.#errorList.length = 0;
|
this.#errorList.length = 0;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简易的解析报错栈堆位置信息的函数
|
||||||
|
*
|
||||||
|
* @param {string} urlLike
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
export function extractLocation(urlLike) {
|
||||||
|
// 不存在地址信息的字符串
|
||||||
|
if (!/:/.test(urlLike)) {
|
||||||
|
return [urlLike];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 捕获位置用到的正则
|
||||||
|
const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/;
|
||||||
|
const parts = regExp.exec(urlLike.replace(/[()]/g, ''));
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return [parts[1], parts[2] || void 0, parts[3] || void 0];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler
|
* @typedef {import('../interface/promise-error-handler').PromiseErrorHandler} PromiseErrorHandler
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* 关于除已实现浏览器外其余浏览器的异步错误处理
|
* 关于除已实现浏览器外其余浏览器的异步错误处理
|
||||||
*
|
*
|
||||||
* 很遗憾,对于这类浏览器,因为标准未涉及报错栈堆或地址及行列号,故我们只能直接,暴力地throw出我们捕获道德错误,
|
* 很遗憾,对于这类浏览器,因为标准未涉及报错栈堆或地址及行列号,故我们只能直接,暴力地throw出我们捕获到的错误,
|
||||||
*
|
*
|
||||||
* 尽管我们还是会为了这类浏览器判断是不是捕获到了一个`Error`
|
* 尽管我们还是会为了这类浏览器判断是不是捕获到了一个`Error`
|
||||||
*
|
*
|
||||||
|
|