Add the handler mechanic, property operation methods, and greatly optimize stratagem mode.

This commit is contained in:
Tipx-L 2023-10-23 06:46:29 -07:00
parent 9e9283ecaf
commit 661813cdc8
5 changed files with 686 additions and 572 deletions

View File

@ -141,7 +141,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){
var target=_status.event.player; var target=_status.event.player;
var evt=_status.event.getParent(); var evt=_status.event.getParent();
var bool=true; var bool=true;
if(_status.event.shanRequired>1&&!get.is.object(card)&&target.countCards('h','shan')<_status.event.shanRequired){ if(_status.event.shanRequired>1&&!get.is.object(card)&&target.countCards('h','shan')<_status.event.shanRequired-(_status.event.shanIgnored||0)){
bool=false; bool=false;
} }
else if(target.hasSkillTag('useShan')){ else if(target.hasSkillTag('useShan')){

File diff suppressed because it is too large Load Diff

View File

@ -1178,8 +1178,9 @@ body>.background.upper {
z-index: -4 z-index: -4
} }
body>.background.land { body>.background.land {
background-position: center;
background-size: cover;
transition: all 2s; transition: all 2s;
background-size:cover;
} }
.popup:not(.guanxing) { .popup:not(.guanxing) {
@ -3500,9 +3501,13 @@ div:not(.handcards)>.card>.info>span,
animation: config 0.5s; animation: config 0.5s;
-webkit-animation: config 0.5s; -webkit-animation: config 0.5s;
} }
.flash { .flash,
animation: flash 1s; .flash-animation-iteration-count-infinite {
-webkit-animation: flash 1s; animation-name: flash;
animation-duration: 1s;
}
.flash-animation-iteration-count-infinite {
animation-iteration-count: infinite;
} }
.flip { .flip {
animation: flip 1s; animation: flip 1s;
@ -3884,6 +3889,10 @@ div:hover>.intro {
.player .identity[data-color="zhu"], .player .identity[data-color="zhu"],
.player .identity[data-color="truezhu"], .player .identity[data-color="truezhu"],
.player .identity[data-color="enemy"], .player .identity[data-color="enemy"],
div[data-nature='zhu'],
span[data-nature='zhu'],
div[data-nature='enemy'],
span[data-nature='enemy'],
div[data-nature='fire'], div[data-nature='fire'],
span[data-nature='fire'] { span[data-nature='fire'] {
text-shadow: black 0 0 1px,rgba(232, 53, 53,1) 0 0 2px,rgba(232, 53, 53,1) 0 0 5px,rgba(232, 53, 53,1) 0 0 10px, text-shadow: black 0 0 1px,rgba(232, 53, 53,1) 0 0 2px,rgba(232, 53, 53,1) 0 0 5px,rgba(232, 53, 53,1) 0 0 10px,
@ -3936,6 +3945,8 @@ span[data-nature='firemx'] {
.player .identity[data-color="qun"], .player .identity[data-color="qun"],
.player .identity[data-color="neutral"], .player .identity[data-color="neutral"],
.player .identity[data-color="friend2"], .player .identity[data-color="friend2"],
div[data-nature='zhong'],
span[data-nature='zhong'],
div[data-nature='metal'], div[data-nature='metal'],
span[data-nature='metal'] { span[data-nature='metal'] {
text-shadow: black 0 0 1px,rgba(255, 203, 0,1) 0 0 2px,rgba(255, 203, 0,1) 0 0 5px,rgba(255, 203, 0,1) 0 0 10px, text-shadow: black 0 0 1px,rgba(255, 203, 0,1) 0 0 2px,rgba(255, 203, 0,1) 0 0 5px,rgba(255, 203, 0,1) 0 0 10px,
@ -4006,6 +4017,8 @@ span[data-nature='qunmm'] {
.player .identity[data-color="rYe"], .player .identity[data-color="rYe"],
.player .identity[data-color="bYe"], .player .identity[data-color="bYe"],
.player .identity[data-color="jin"], .player .identity[data-color="jin"],
div[data-nature='nei'],
span[data-nature='nei'],
div[data-nature='thunder'], div[data-nature='thunder'],
span[data-nature='thunder'] { span[data-nature='thunder'] {
text-shadow: rgba(100, 74, 139,1) 0 0 2px,rgba(100, 74, 139,1) 0 0 5px,rgba(100, 74, 139,1) 0 0 10px, text-shadow: rgba(100, 74, 139,1) 0 0 2px,rgba(100, 74, 139,1) 0 0 5px,rgba(100, 74, 139,1) 0 0 10px,
@ -4041,6 +4054,8 @@ span[data-nature='kamimm'] {
.player .identity[data-color="fan"], .player .identity[data-color="fan"],
.player .identity[data-color="wu"], .player .identity[data-color="wu"],
div[data-nature='fan'],
span[data-nature='fan'],
div[data-nature='wood'], div[data-nature='wood'],
span[data-nature='wood'] { span[data-nature='wood'] {
text-shadow: rgba(57, 123, 4,1) 0 0 2px,rgba(57, 123, 4,1) 0 0 5px,rgba(57, 123, 4,1) 0 0 10px, text-shadow: rgba(57, 123, 4,1) 0 0 2px,rgba(57, 123, 4,1) 0 0 5px,rgba(57, 123, 4,1) 0 0 10px,
@ -4065,6 +4080,8 @@ span[data-nature='woodmm'] {
.player .identity[data-color="falsezhu"], .player .identity[data-color="falsezhu"],
.player .identity[data-color="friend"], .player .identity[data-color="friend"],
.water, .water,
div[data-nature='friend'],
span[data-nature='friend'],
div[data-nature='water'], div[data-nature='water'],
span[data-nature='water'] { span[data-nature='water'] {
text-shadow: rgba(78, 117, 140,1) 0 0 2px,rgba(78, 117, 140,1) 0 0 5px,rgba(78, 117, 140,1) 0 0 10px, text-shadow: rgba(78, 117, 140,1) 0 0 2px,rgba(78, 117, 140,1) 0 0 5px,rgba(78, 117, 140,1) 0 0 10px,

View File

@ -685,8 +685,8 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
var next=game.createEvent('chooseCharacter'); var next=game.createEvent('chooseCharacter');
next.showConfig=true; next.showConfig=true;
next.addPlayer=function(player){ next.addPlayer=function(player){
var list=lib.config.mode_config.identity.identity[game.players.length-3].slice(0); var list=get.identityList(game.players.length-1);
var list2=lib.config.mode_config.identity.identity[game.players.length-2].slice(0); var list2=get.identityList(game.players.length);
for(var i=0;i<list.length;i++) list2.remove(list[i]); for(var i=0;i<list.length;i++) list2.remove(list[i]);
player.identity=list2[0]; player.identity=list2[0];
player.setIdentity('cai'); player.setIdentity('cai');

View File

@ -263,8 +263,8 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
game.broadcastAll(stratagemBroadcast); game.broadcastAll(stratagemBroadcast);
if(_status.connectMode&&!_status.postReconnect.stratagemReinit) _status.postReconnect.stratagemReinit=[stratagemBroadcast,{}]; if(_status.connectMode&&!_status.postReconnect.stratagemReinit) _status.postReconnect.stratagemReinit=[stratagemBroadcast,{}];
for(var current of game.players){ for(var current of game.players){
if(current.identity=='zhu') current.addSkill('stratagem_show_zhu'); if(current.identity=='zhu') current.addSkill('stratagem_monarchy');
if(current.identity=='fan') current.addSkill('stratagem_show_fan'); if(current.identity=='fan') current.addSkill('stratagem_revitalization');
} }
} }
if(game.zhu==game.me&&game.zhu.identity!='zhu'&&_status.brawl&&_status.brawl.identityShown){ if(game.zhu==game.me&&game.zhu.identity!='zhu'&&_status.brawl&&_status.brawl.identityShown){
@ -340,7 +340,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
marktext:'🔥', marktext:'🔥',
intro:{ intro:{
name:'怒气', name:'怒气',
content:'当前怒气值:#/3', content:'当前怒气值:#',
}, },
}, },
}, },
@ -349,7 +349,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
//game.addVideo('markSkill',game.players[i],['stratagem_fury']); //game.addVideo('markSkill',game.players[i],['stratagem_fury']);
game.players[i].ai.shown=0; game.players[i].ai.shown=0;
} }
game.neiDoCamouflage(); game.stratagemCamouflage();
} }
"step 6" "step 6"
if(_status.mode!='stratagem') event.beginner=_status.firstAct2||game.zhong||game.zhu||_status.firstAct||game.me; if(_status.mode!='stratagem') event.beginner=_status.firstAct2||game.zhong||game.zhu||_status.firstAct||game.me;
@ -1254,30 +1254,27 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
ui.arena.classList.remove('choose-character'); ui.arena.classList.remove('choose-character');
},500); },500);
},result2,result); },result2,result);
for(var i in result2){ for(var i in result2){
if(!lib.playerOL[i].name){ if(!lib.playerOL[i].name){
lib.playerOL[i].init(result2[i][0],result2[i][1]); lib.playerOL[i].init(result2[i][0],result2[i][1]);
} }
if(result[i]&&result[i].length) lib.playerOL[i].changeGroup(result[i],false,false); if(result[i]&&result[i].length) lib.playerOL[i].changeGroup(result[i],false,false);
} }
for(var i=0;i<game.players.length;i++){ for(var i=0;i<game.players.length;i++){
_status.characterlist.remove(game.players[i].name); _status.characterlist.remove(game.players[i].name);
_status.characterlist.remove(game.players[i].name1); _status.characterlist.remove(game.players[i].name1);
_status.characterlist.remove(game.players[i].name2); _status.characterlist.remove(game.players[i].name2);
} }
var list=['stratagem_fury','stratagem_fury_insight','stratagem_expose','stratagem_shan_ai','stratagem_card_effect']; ['stratagem_gain','stratagem_insight','stratagem_expose'].forEach(globalSkill=>game.addGlobalSkill(globalSkill));
for(var i=0;i<list.length;i++){
game.addGlobalSkill(list[i]);
}
game.players.forEach(current=>{ game.players.forEach(current=>{
current.storage.zhibi=[]; current.storage.zhibi=[];
current.storage.zhibi_for=[]; current.storage.zhibi_for=[];
current.markSkill('stratagem_fury'); current.markSkill('stratagem_fury');
}); });
setTimeout(function(){ setTimeout(function(){
ui.arena.classList.remove('choose-character'); ui.arena.classList.remove('choose-character');
},500); },500);
@ -2085,10 +2082,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
} }
"step 4" "step 4"
if(event.stratagemMode){ if(event.stratagemMode){
var list=['stratagem_fury','stratagem_fury_insight','stratagem_expose','stratagem_shan_ai','stratagem_card_effect']; ['stratagem_gain','stratagem_insight','stratagem_expose'].forEach(globalSkill=>game.addGlobalSkill(globalSkill));
for(var i=0;i<list.length;i++){
game.addGlobalSkill(list[i]);
}
game.players.forEach(i=>{ game.players.forEach(i=>{
i.storage.zhibi=[]; i.storage.zhibi=[];
i.storage.zhibi_for=[]; i.storage.zhibi_for=[];
@ -2531,14 +2525,14 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
},500); },500);
}); });
}, },
neiDoCamouflage:function(){ stratagemCamouflage:function(){
var next=game.createEvent('neiDoCamouflage'); var next=game.createEvent('stratagemCamouflage');
next.players=game.players.slice(); next.players=game.players.slice();
if(_status.connectMode){ if(_status.connectMode){
next.setContent('neiDoCamouflageOL'); next.setContent('stratagemCamouflageOL');
} }
else{ else{
next.setContent('neiDoCamouflage'); next.setContent('stratagemCamouflage');
} }
}, },
}, },
@ -2593,11 +2587,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
sheshen:'舍身', sheshen:'舍身',
sheshen_info:'锁定技,主公处于濒死状态即将死亡时,令主公+1体力上限回复体力至X点X为你的体力值数获得你的所有牌然后你死亡。', sheshen_info:'锁定技,主公处于濒死状态即将死亡时,令主公+1体力上限回复体力至X点X为你的体力值数获得你的所有牌然后你死亡。',
yexinbilu:'野心毕露', yexinbilu:'野心毕露',
stratagem_fury:'怒气', stratagem_insight:'洞察'
stratagem_fury_insight:'洞察',
stratagem_fury_cost1:'1🔥',
stratagem_fury_cost2:'2🔥',
stratagem_fury_cost3:'3🔥',
}, },
element:{ element:{
player:{ player:{
@ -2608,17 +2598,6 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
next.setContent('stratagemInsight'); next.setContent('stratagemInsight');
return next; return next;
}, },
changeFury:function(num){
var player=this;
if(!player.storage.stratagem_fury) player.storage.stratagem_fury=0;
var tmp=player.storage.stratagem_fury;
player.storage.stratagem_fury+=num;
player.storage.stratagem_fury=Math.max(Math.min(player.storage.stratagem_fury,_status.stratagemFuryMax),0);
var del=player.storage.stratagem_fury-tmp;
if(del===0) return;
game.log(player,del>=0?'获得了':'失去了',get.cnNumber(Math.abs(del))+'点<span class="firetext">怒气</span>');
player.markSkill('stratagem_fury');
},
addExpose:function(num){ addExpose:function(num){
if(!game.zhu||!game.zhu.isZhu||!game.zhu.identityShown) return; if(!game.zhu||!game.zhu.isZhu||!game.zhu.identityShown) return;
if(typeof this.ai.shown=='number'&&!this.identityShown&&this.ai.shown<1){ if(typeof this.ai.shown=='number'&&!this.identityShown&&this.ai.shown<1){
@ -2964,180 +2943,187 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
} }
}, },
content:{ content:{
stratagemInsight:function(event,map){ stratagemInsight:event=>{
'step 0' 'step 0'
// var player=map.player,target=map.target; game.log(player,'洞察了',target,'与其的阵营关系');
if(!player.storage.stratagem_fury){event.finish();return;}
// yield player.changeFury(-1);
player.changeFury(-1);
'step 1' 'step 1'
if(!player.storage.zhibi) player.storage.zhibi=[]; var storage=player.storage;
if(!player.storage.zhibi.contains(target)) player.storage.zhibi.push(target); if(!storage.zhibi) storage.zhibi=[];
var res=get.insightResult(player,target); var zhibi=storage.zhibi;
event.insightResult=res; if(!zhibi.includes(target)) zhibi.push(target);
var insightResult=event.insightResult=get.insightResult(player,target);
event.videoId=lib.status.videoId++; event.videoId=lib.status.videoId++;
var send=(target,res,id)=>{ var send=(clientTarget,clientInsightResult,id)=>{
var str=get.translation(target)+'是'+get.translation(res+'2')+'<br>'; var classList=clientTarget.classList,nonStratagemInsightFlashing=classList.contains('flash-animation-iteration-count-infinite');
var dialog=ui.create.dialog(str,'forcebutton'); if(nonStratagemInsightFlashing) clientTarget.nonStratagemInsightFlashing=true;
ui.create.spinningIdentityCard(res,dialog); else classList.add('flash-animation-iteration-count-infinite');
var identity=get.translation(`${clientInsightResult}2`);
clientTarget.prompt(identity,clientInsightResult);
var dialog=ui.create.dialog(`${get.translation(clientTarget)}${identity}<br>`,'forcebutton');
ui.create.spinningIdentityCard(clientInsightResult,dialog);
var control=ui.create.control('ok',()=>{ var control=ui.create.control('ok',()=>{
dialog.close(); dialog.close();
control.close(); control.close();
_status.imchoosing=false; _status.imchoosing=false;
_status.event._result={bool:true}; _status.event._result={
bool:true
};
game.resume(); game.resume();
}); });
dialog.videoId=id; dialog.videoId=id;
game.pause(); game.pause();
game.countChoose(); game.countChoose();
}; };
var hint=(player,target,id)=>{ game.broadcastAll((clientPlayer,clientTarget,id)=>{
if(player==game.me) return; if(clientPlayer!=game.me) ui.create.dialog(`${get.translation(clientPlayer)}正在洞察${get.translation(clientTarget)}的阵营...<br>`).videoId=id;
var str=get.translation(player)+'正在洞察'+get.translation(target)+'的阵营...<br>'; },player,target,event.videoId);
ui.create.dialog(str).videoId=id; if(event.isMine()) send(target,insightResult,event.videoId);
};
game.broadcastAll(hint,player,target,event.videoId);
if(event.isMine()){
send(target,res,event.videoId);
}
else if(event.isOnline()){ else if(event.isOnline()){
event.player.send(send,target,res,event.videoId); player.send(send,target,insightResult,event.videoId);
event.player.wait(); player.wait();
game.pause(); game.pause();
} }
// yield next;
'step 2' 'step 2'
game.broadcastAll('closeDialog',event.videoId); game.broadcastAll('closeDialog',event.videoId);
if(!_status.connectMode&&get.config('auto_mark_identity')&&!target.node.identity.firstChild.innerHTML.length){ if(!_status.connectMode&&get.config('auto_mark_identity')&&!target.node.identity.firstChild.innerHTML.length) game.broadcastAll((clientPlayer,clientTarget,insightResult)=>{
game.broadcastAll(function(player,target,event){ if(clientPlayer.isUnderControl(true)) clientTarget.setIdentity(insightResult);
if(player.isUnderControl(true)) target.setIdentity(event.insightResult); },player,target,event.insightResult);
},player,target,event); var afterInsight=clientTarget=>{
} clientTarget.unprompt();
}, if(clientTarget.nonStratagemInsightFlashing){
neiDoCamouflage:function(){ delete clientTarget.nonStratagemInsightFlashing;
'step 0' return;
var list=[];
for(var i=0;i<game.players.length;i++){
if(game.players[i].identity=='fan'){
list.push(game.players[i]);
} }
} var classList=clientTarget.classList;
var target=list.randomGet(); if(classList.contains('flash-animation-iteration-count-infinite')) classList.remove('flash-animation-iteration-count-infinite');
event.target=target; };
target.ai.stratagemCamouflage=true; if(event.isMine()) afterInsight(target);
var neis=game.filterPlayer(i=>i.identity=='nei'); else if(event.isOnline()) player.send(afterInsight,target);
if(event.players.includes(game.me)&&game.me.identity=='nei'){ },
var str=get.translation(target)+'是反贼<br>'; stratagemCamouflage:()=>{
'step 0'
var camouflaged=event.targets=game.players.filter(current=>current.identity=='fan'&&!current.ai.stratagemCamouflage).randomGets(Math.max(Math.round(get.population()/6),1));
camouflaged.forEach(current=>current.ai.stratagemCamouflage=true);
var me=game.me;
if(event.players.includes(me)&&me.identity=='nei'){
event.videoId=lib.status.videoId++; event.videoId=lib.status.videoId++;
var dialog=ui.create.dialog(str,'forcebutton'); var rebel=get.translation('fan2'),dialog=ui.create.dialog(`${get.translation(camouflaged)}${rebel}<br>`,'forcebutton');
ui.create.spinningIdentityCard('fan',dialog); ui.create.spinningIdentityCard('fan',dialog);
dialog.videoId=event.videoId; dialog.videoId=event.videoId;
game.me.chooseControl('ok').set('dialog',dialog); camouflaged.forEach(victim=>{
} var classList=victim.classList,nonCamouflageFlashing=classList.contains('flash-animation-iteration-count-infinite');
for(var current of neis){ if(nonCamouflageFlashing) victim.nonCamouflageFlashing=true;
if(!current.storage.zhibi) current.storage.zhibi=[]; else classList.add('flash-animation-iteration-count-infinite');
if(!current.storage.zhibi.includes(target)) current.storage.zhibi.push(target); victim.prompt(rebel,'fan');
});
me.chooseControl('ok').set('dialog',dialog);
} }
game.filterPlayer(current=>{
if(current.identity!='nei') return;
var storage=current.storage;
if(!storage.zhibi) storage.zhibi=[];
storage.zhibi.addArray(camouflaged);
});
'step 1' 'step 1'
if(game.me.identity=='nei'&&get.config('nei_auto_mark_camouflage')){ targets.forEach(current=>{
event.target.setIdentity(); if(game.me.identity=='nei'&&get.config('nei_auto_mark_camouflage')) current.setIdentity();
} current.unprompt();
if(current.nonCamouflageFlashing){
delete current.nonCamouflageFlashing;
return;
}
var classList=current.classList;
if(classList.contains('flash-animation-iteration-count-infinite')) classList.remove('flash-animation-iteration-count-infinite');
});
}, },
neiDoCamouflageOL:function(){ stratagemCamouflageOL:()=>{
'step 0' 'step 0'
var send=function(target,id){ var send=(clientCamouflaged,id,online)=>{
if(game.me.identity=='nei'){ var me=game.me;
if(!game.me.storage.zhibi) game.me.storage.zhibi=[]; if(me.identity=='nei'){
if(!game.me.storage.zhibi.contains(target)) game.me.storage.zhibi.push(target); var storage=me.storage;
var str=get.translation(target)+'是反贼<br>'; if(!storage.zhibi) storage.zhibi=[];
var dialog=ui.create.dialog(str,'forcebutton'); storage.zhibi.addArray(clientCamouflaged);
var rebel=get.translation('fan2'),dialog=ui.create.dialog(`${get.translation(clientCamouflaged)}${rebel}<br>`,'forcebutton');
ui.create.spinningIdentityCard('fan',dialog); ui.create.spinningIdentityCard('fan',dialog);
dialog.videoId=id; dialog.videoId=id;
game.me.chooseControl('ok').set('dialog',dialog); clientCamouflaged.forEach(victim=>{
var classList=victim.classList,nonCamouflageFlashing=classList.contains('flash-animation-iteration-count-infinite');
if(nonCamouflageFlashing) victim.nonCamouflageFlashing=true;
else classList.add('flash-animation-iteration-count-infinite');
victim.prompt(rebel,'fan');
});
me.chooseControl('ok').set('dialog',dialog);
} }
else{ else ui.create.dialog('请等待内奸身份确认...').videoId=id;
var dialog=ui.create.dialog('请等待内奸身份确认...'); if(online) game.resume();
dialog.videoId=id;
}
game.resume();
}; };
var list=[]; var camouflaged=event.targets=game.players.filter(current=>current.identity=='fan'&&!current.ai.stratagemCamouflage).randomGets(Math.max(Math.round(get.population()/6),1));
for(var i=0;i<game.players.length;i++){ camouflaged.forEach(current=>current.ai.stratagemCamouflage=true);
if(game.players[i].identity=='fan'){
list.push(game.players[i]);
}
}
var target=list.randomGet();
target.ai.stratagemCamouflage=true;
event.videoId=lib.status.videoId++; event.videoId=lib.status.videoId++;
event.ai_targets=[];
var time=10000; var time=10000;
if(lib.configOL&&lib.configOL.choose_timeout) time=parseInt(lib.configOL.choose_timeout)*1000; if(lib.configOL&&lib.configOL.choose_timeout) time=parseInt(lib.configOL.choose_timeout)*1000;
for(var i=0;i<event.players.length;i++){ var aiTargets=event.aiTargets=[];
event.players[i].showTimer(time); event.players.forEach(current=>{
if(event.players[i].isOnline()){ current.showTimer(time);
event.players[i].send(send,target,event.videoId); if(current.isOnline()){
event.players[i].wait(); current.send(send,camouflaged,event.videoId,true);
if(event.players[i].identity=='nei'){ current.wait();
event.withol=true; if(current.identity=='nei') event.withOL=true;
} return;
} }
else if(event.players[i]==game.me){ var me=game.me;
event.withme=true; if(current==me){
if(game.me.identity=='nei'){ event.withMe=true;
var str=get.translation(target)+'是反贼<br>'; send(camouflaged,event.videoId);
var dialog=ui.create.dialog(str,'forcebutton'); if(me.identity=='nei') me.wait();
ui.create.spinningIdentityCard('fan',dialog); else event._result={
dialog.videoId=event.videoId; bool:true
game.me.chooseControl('ok').set('dialog',dialog); };
game.me.wait(); return;
}
else{
var dialog=ui.create.dialog('请等待内奸身份确认...');
dialog.videoId=event.videoId;
event._result={bool:true};
}
} }
else{ if(current.identity=='nei') aiTargets.push(current);
if(event.players[i].identity=='nei'){ });
event.ai_targets.push(event.players[i]); if(!aiTargets.length) return;
} aiTargets.randomSort();
} new Promise(resolve=>setTimeout(resolve,Math.ceil(5000+5000*Math.random()))).then(()=>{
} var interval=setInterval(()=>{
if(event.ai_targets.length){ aiTargets.shift();
event.ai_targets.randomSort(); if(aiTargets.length) return;
setTimeout(function(){ clearInterval(interval);
event.interval=setInterval(function(){ if(event.withAI) game.resume();
event.ai_targets.shift(); },Math.ceil(500+500*Math.random()))
if(!event.ai_targets.length){ });
clearInterval(event.interval);
if(event.withai) game.resume();
}
},Math.ceil(100+500*Math.random()));
},Math.ceil(2500+1000*Math.random()))
}
'step 1' 'step 1'
if(event.withme){ if(event.withMe) game.me.unwait(result);
game.me.unwait(result);
}
'step 2' 'step 2'
if(event.withol&&!event.resultOL){ if(event.withOL&&!event.resultOL) game.pause();
game.pause();
}
'step 3' 'step 3'
if(event.ai_targets.length>0){ if(!event.aiTargets.length) return;
event.withai=true; event.withAI=true;
game.pause(); game.pause();
}
'step 4' 'step 4'
game.broadcastAll('closeDialog',event.videoId); game.broadcastAll('closeDialog',event.videoId);
for(var i=0;i<event.players.length;i++){ event.players.forEach(current=>current.hideTimer());
event.players[i].hideTimer(); var afterCamouflage=clientCamouflaged=>clientCamouflaged.forEach(victim=>{
} victim.unprompt();
}, if(victim.nonCamouflageFlashing){
}, delete victim.nonCamouflageFlashing;
return;
}
var classList=victim.classList;
if(classList.contains('flash-animation-iteration-count-infinite')) classList.remove('flash-animation-iteration-count-infinite');
});
event.players.forEach(current=>{
if(current.isOnline()){
current.send(afterCamouflage,targets);
return;
}
var me=game.me;
if(current==me&&me.identity=='nei') afterCamouflage(targets);
});
}
}
}, },
get:{ get:{
rawAttitude:function(from,to){ rawAttitude:function(from,to){
@ -3194,7 +3180,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
} }
if(to.identity=='fan'&&from.identity=='nei'&&zhibi.contains(game.zhu)&&game.players.filter(i=>i!=from&&!zhibi.contains(i)).map(i=>i.identity).reduce((p,c)=>(!p.contains(c)?(p.push(c)&&p):p),[]).length==1) return real; if(to.identity=='fan'&&from.identity=='nei'&&zhibi.contains(game.zhu)&&game.players.filter(i=>i!=from&&!zhibi.contains(i)).map(i=>i.identity).reduce((p,c)=>(!p.contains(c)?(p.push(c)&&p):p),[]).length==1) return real;
for(var fan of game.dead){ for(var fan of game.dead){
if(fan.identity!='fan'||!fan.storage.stratagem_show_fan) continue; if(fan.identity!='fan'||!fan.storage.stratagem_revitalization) continue;
for(var current of fan.storage.zhibi_for){ for(var current of fan.storage.zhibi_for){
if(to==current){ if(to==current){
return real; return real;
@ -3705,86 +3691,51 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
if(from.ai.stratagemCamouflage||to.ai.stratagemCamouflage) return enemy; if(from.ai.stratagemCamouflage||to.ai.stratagemCamouflage) return enemy;
if(from.identity==to.identity||from.identity=='zhu'&&to.identity=='zhong'||from.identity=='zhong'&&to.identity=='zhu') return friend; if(from.identity==to.identity||from.identity=='zhu'&&to.identity=='zhong'||from.identity=='zhong'&&to.identity=='zhu') return friend;
return enemy; return enemy;
},
/**
* @param {number} numberOfPlayers
* @returns {string[]}
*/
identityList:numberOfPlayers=>{
const modeConfig=lib.config.mode_config;
if(modeConfig){
const identityConfig=modeConfig.identity;
if(identityConfig){
const identityLists=identityConfig.identity;
if(identityLists){
const identityList=identityLists[numberOfPlayers-2];
if(Array.isArray(identityList)) return identityList.slice();
}
}
}
const numberOfPlayersExceptLord=numberOfPlayers-1,numberOfLoyalists=Math.round(numberOfPlayersExceptLord*3/9),numberOfSpys=Math.round(numberOfPlayersExceptLord*2/9);
return ['zhu'].concat(Array.from({
length:numberOfLoyalists
},()=>'zhong'),Array.from({
length:numberOfSpys
},()=>'nei'),Array.from({
length:numberOfPlayersExceptLord-numberOfLoyalists-numberOfSpys
},()=>'fan'));
} }
}, },
skill:{ skill:{
stratagem_fury:{ stratagem_gain:{
mark:true,
marktext:'🔥',
silent:true, silent:true,
charlotte:true, charlotte:true,
ruleSkill:true, ruleSkill:true,
trigger:{ trigger:{
player:['phaseBegin','damageEnd'], player:['phaseBegin','damageEnd']
}, },
content:function(){ content:()=>{
player.changeFury(trigger.name=='damage'?trigger.num:1); player.changeFury(trigger.name=='damage'?trigger.num:1,true);
},
intro:{
name:'怒气',
content:function(storage,player){
return '当前怒气值:'+(storage||0)+'/'+_status.stratagemFuryMax;
},
},
subSkill:{
insight:{
trigger:{
source:'damageSource',
global:'loseHpEnd',
},
filter:function(event,player){
if(event.player.identityShown) return false;
var source=event.source;
if(event.name=='loseHp'){
if(event.getParent()._trigger) source=event.getParent()._trigger.source;
}
return player==source&&player.storage.stratagem_fury>0&&event.player&&event.player.isIn()&&event.player!=player;
},
logTarget:'player',
prompt2:function(event,player){
return '消耗1点怒气洞察'+get.translation(event.player)+'的身份';
},
check:function(event,player){
if(player.storage.zhibi&&player.storage.zhibi.contains(event.player)||player.storage.zhibi_for&&player.storage.zhibi_for.contains(event.player)) return false;
if(get.population('zhong')==0&&player.identity=='fan') return false;
return Math.abs(get.attitude(player,event.player))<=1;
},
content:function(){
game.log(player,'洞察了',trigger.player,'与其的阵营关系');
player.insightInto(trigger.player);
},
ai:{
order:15,
}
},
} }
}, },
stratagem_show_zhu:{ stratagem_insight:{
trigger:{
source:'damageSource',
global:'loseHpEnd',
},
filter:function(event,player){
if(event.player.identityShown) return false;
var source=event.source;
if(event.name=='loseHp'){
if(event.getParent()._trigger) source=event.getParent()._trigger.source;
}
return player==source&&player.storage.stratagem_fury>0&&event.player&&event.player.isIn()&&event.player!=player;
},
logTarget:'player',
prompt2:function(event,player){
return '消耗1点怒气洞察'+get.translation(event.player)+'的身份';
},
check:function(event,player){
if(player.storage.zhibi&&player.storage.zhibi.contains(event.player)||player.storage.zhibi_for&&player.storage.zhibi_for.contains(event.player)) return false;
if(get.population('zhong')==0&&player.identity=='fan') return false;
return Math.abs(get.attitude(player,event.player))<=1;
},
content:function(){
player.changeFury(-1,true);
player.insightInto(trigger.player);
},
ai:{
order:15,
}
},
stratagem_monarchy:{
trigger:{ trigger:{
player:['dying','phaseBefore'], player:['dying','phaseBefore'],
global:'dieAfter', global:'dieAfter',
@ -3798,7 +3749,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
charlotte:true, charlotte:true,
ruleSkill:true, ruleSkill:true,
filter:function(event,player){ filter:function(event,player){
if(player.storage.stratagem_show_zhu) return false; if(player.storage.stratagem_monarchy) return false;
if(player.identity=='zhu'){ if(player.identity=='zhu'){
if(event.player==player){ if(event.player==player){
if(event.name=='dying') return true; if(event.name=='dying') return true;
@ -3812,7 +3763,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
'step 0' 'step 0'
if(trigger.name=='dying') game.delayx(); if(trigger.name=='dying') game.delayx();
'step 1' 'step 1'
player.storage.stratagem_show_zhu=true; player.storage.stratagem_monarchy=true;
game.zhu=game.zhu||player; game.zhu=game.zhu||player;
game.broadcastAll(function(player){ game.broadcastAll(function(player){
game.zhu=player; game.zhu=player;
@ -3847,7 +3798,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
} }
} }
}, },
stratagem_show_fan:{ stratagem_revitalization:{
trigger:{ trigger:{
player:'dying', player:'dying',
}, },
@ -3857,13 +3808,13 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
charlotte:true, charlotte:true,
ruleSkill:true, ruleSkill:true,
filter:function(event,player){ filter:function(event,player){
return player.ai.stratagemCamouflage&&event.player==player&&!game.dead.length&&player.storage.stratagem_fury>=2&&!player.storage.stratagem_show_fan; return player.ai.stratagemCamouflage&&event.player==player&&game.dead.length<Math.max(Math.round(get.population()/6),1)&&player.storage.stratagem_fury>=2&&!player.storage.stratagem_revitalization;
}, },
content:function(){ content:function(){
'step 0' 'step 0'
game.delayx(); game.delayx();
'step 1' 'step 1'
player.storage.stratagem_show_fan=true; player.storage.stratagem_revitalization=true;
game.broadcastAll(function(player){ game.broadcastAll(function(player){
player.identityShown=true; player.identityShown=true;
player.ai.shown=1; player.ai.shown=1;
@ -3875,7 +3826,7 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
game.delay(2); game.delay(2);
player.playerfocus(800); player.playerfocus(800);
'step 2' 'step 2'
player.changeFury(-player.storage.stratagem_fury); player.changeFury(-player.storage.stratagem_fury,true);
player.discard(player.getCards('hej')); player.discard(player.getCards('hej'));
player.link(false); player.link(false);
player.turnOver(false); player.turnOver(false);
@ -3891,76 +3842,12 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
filter:function(event,player){ filter:function(event,player){
if(event.targets[0]==player) return false; if(event.targets[0]==player) return false;
return event.targets.length==1&&event.targets[0]&&((player.storage.zhibi.contains(event.targets[0])||event.targets[0].identityShown) || return event.targets.length==1&&event.targets[0]&&((player.storage.zhibi.contains(event.targets[0])||event.targets[0].identityShown) ||
game.players.slice().concat(game.dead).filter(current=>(current.storage.stratagem_show_fan||current.storage.stratagem_show_zhu)&&current.identityShown&&current.storage.zhibi_for.contains(event.targets[0])).length); game.players.slice().concat(game.dead).filter(current=>(current.storage.stratagem_revitalization||current.storage.stratagem_monarchy)&&current.identityShown&&current.storage.zhibi_for.contains(event.targets[0])).length);
}, },
content:function(){ content:function(){
if(!trigger.targets[0].storage.zhibi_for) trigger.targets[0].storage.zhibi_for=[]; if(!trigger.targets[0].storage.zhibi_for) trigger.targets[0].storage.zhibi_for=[];
if(!trigger.targets[0].storage.zhibi_for.contains(player)) trigger.targets[0].storage.zhibi_for.push(player); if(!trigger.targets[0].storage.zhibi_for.contains(player)) trigger.targets[0].storage.zhibi_for.push(player);
} }
},
stratagem_shan_ai:{
trigger:{
player:'chooseToUseBegin',
},
filter:function(event,player){
if(event.getParent().name!='sha') return false;
return event.getParent().target==player;
},
forced:true,
silent:true,
forced:true,
charlotte:true,
content:function(){
var evt=trigger.getParent();
trigger.set('prompt','请使用一张闪响应杀');
trigger.set('filterCard',function(card,player){
if(get.name(card)!='shan') return false;
return lib.filter.cardEnabled(card,player,'forceEnable');
});
var req=evt.shanRequired;
if(req>1){
trigger.set('prompt2','(共需使用'+req+'张普通闪,或'+Math.ceil(req/2)+'张强化闪)');
}
else if(evt.card.nature=='stab'){
trigger.set('prompt2','(在此之后仍需弃置一张手牌)');
}
trigger.set('ai1',function(card){
var target=_status.event.player;
var evt=_status.event.getParent(2);
var bool=true;
if(_status.event.getParent().shanRequired>1&&!get.is.object(card)&&(target.countCards('h','shan')<_status.event.getParent().shanRequired&&!(target.storage.stratagem_fury>=1&&target.countCards('h','shan')==1&&_status.event.getParent().shanRequired<=2))){
bool=false;
}
else if(target.hasSkillTag('useShan')){
bool=true;
}
else if(get.damageEffect(target,evt.player,target,evt.card.nature)>=0) bool=false;
if(bool){
return get.order(card);
}
return 0;
}).set('shanRequired',evt.shanRequired);
},
},
stratagem_card_effect:{
trigger:{
player:['useCard1'],
},
forced:true,
silent:true,
forced:true,
charlotte:true,
filter:function(event,player,name){
return event.card&&event.card.storage&&event.card.storage.stratagemBuffed&&event.cards.length;
},
content:function(){
game.broadcastAll(function(cards){
for(var i of cards){
i.clone.classList.add('stratagem-fury-glow');
}
},trigger.cards);
}
}, },
yexinbilu:{ yexinbilu:{
enable:'phaseUse', enable:'phaseUse',