Merge pull request #583 from Tipx-L/PR-Branch

The Multiplayer Update: Extra.
This commit is contained in:
Spmario233 2023-10-26 22:48:07 +08:00 committed by GitHub
commit a71817b5c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 149 additions and 122 deletions

View File

@ -5742,7 +5742,7 @@
name:'游戏人数', name:'游戏人数',
init:'8', init:'8',
get item(){ get item(){
const minimumNumberOfPlayers=3,maximumNumberOfPlayers=Math.max(_status.maximumNumberOfPlayers||10,minimumNumberOfPlayers),item={}; const minimumNumberOfPlayers=2,maximumNumberOfPlayers=Math.max(_status.maximumNumberOfPlayers||12,minimumNumberOfPlayers),item={};
for(let playerNumber=minimumNumberOfPlayers;playerNumber<=maximumNumberOfPlayers;playerNumber++){ for(let playerNumber=minimumNumberOfPlayers;playerNumber<=maximumNumberOfPlayers;playerNumber++){
item[playerNumber]=`${get.cnNumber(playerNumber)}`; item[playerNumber]=`${get.cnNumber(playerNumber)}`;
} }
@ -11184,10 +11184,10 @@
} }
}, },
layout:function(layout,nosave){ layout:function(layout,nosave){
const previousTransitionDuration=document.documentElement.style.transitionDuration; const loadingScreen=ui.create.div('.loading-screen',document.body),loadingScreenStyle=loadingScreen.style;
document.documentElement.style.transitionDuration='1s'; loadingScreenStyle.animationDuration='1s';
const previousFilter=document.documentElement.style.filter,previousWebkitFilter=document.documentElement.style.webkitFilter; loadingScreenStyle.animationFillMode='forwards';
document.documentElement.style.filter=document.documentElement.style.webkitFilter='brightness(0)'; loadingScreenStyle.animationName='opacity-0-1';
if(layout=='default') layout='mobile'; if(layout=='default') layout='mobile';
if(!nosave) game.saveConfig('layout',layout); if(!nosave) game.saveConfig('layout',layout);
game.layout=layout; game.layout=layout;
@ -11294,18 +11294,12 @@
return new Promise(resolve=>setTimeout(resolve,500)); return new Promise(resolve=>setTimeout(resolve,500));
}).then(()=>{ }).then(()=>{
ui.updatex(); ui.updatex();
ui.create.playerPositions(); ui.updatePlayerPositions();
return new Promise(resolve=>setTimeout(resolve,500)); return new Promise(resolve=>setTimeout(resolve,500));
}).then(()=>{ }).then(()=>{
ui.updatec(); ui.updatec();
if(previousFilter) document.documentElement.style.filter=previousFilter; loadingScreenStyle.animationName='opacity-1-0';
else document.documentElement.style.removeProperty('filter'); loadingScreen.addEventListener('animationend',animationEvent=>animationEvent.target.remove());
if(previousWebkitFilter) document.documentElement.style.webkitFilter=previousWebkitFilter;
else document.documentElement.style.removeProperty('-webkit-filter');
return new Promise(resolve=>setTimeout(resolve,1000));
}).then(()=>{
if(previousTransitionDuration) document.documentElement.style.transitionDuration=previousTransitionDuration;
else document.documentElement.style.removeProperty('transition-duration');
}); });
}, },
background:function(){ background:function(){
@ -23174,6 +23168,11 @@
} }
return list; return list;
} }
/**
* @param {string} [arg1='h']
* @param {string | Record<string, any> | (card: Card) => boolean} [arg2]
* @returns {Card[]}
*/
getCards(arg1,arg2){ getCards(arg1,arg2){
if(typeof arg1!='string'){ if(typeof arg1!='string'){
arg1='h'; arg1='h';
@ -30593,7 +30592,7 @@
else Object.defineProperty(this,key,propertyDescriptor); else Object.defineProperty(this,key,propertyDescriptor);
}); });
if(Array.isArray(numberOrCards)){ if(Array.isArray(numberOrCards)){
const noCards=!('cards' in this); const noCards=!this.cards;
/** /**
* @type {Card[]} * @type {Card[]}
*/ */
@ -30601,8 +30600,8 @@
if(noCards){ if(noCards){
if(!lib.suits.includes(this.suit)) this.suit=get.suit(this); if(!lib.suits.includes(this.suit)) this.suit=get.suit(this);
if(!Object.keys(lib.color).includes(this.color)) this.color=get.color(this); if(!Object.keys(lib.color).includes(this.color)) this.color=get.color(this);
if(!('number' in this)) this.number=get.number(this); if(typeof this.number!='number') this.number=get.number(this);
if(!('nature' in this)) this.nature=get.nature(this); if(!this.nature) this.nature=get.nature(this);
} }
} }
const info=get.info(this,false); const info=get.info(this,false);
@ -30615,9 +30614,8 @@
if(typeof numberOrCards=='number') this.number=numberOrCards; if(typeof numberOrCards=='number') this.number=numberOrCards;
if(typeof name=='string') this.name=name; if(typeof name=='string') this.name=name;
if(typeof nature=='string') this.nature=nature; if(typeof nature=='string') this.nature=nature;
if('suit' in this&&!('color' in this)) this.color=get.color(this); if(!this.storage) this.storage={};
if(!('storage' in this)) this.storage={}; if(!this.cards) this.cards=[];
if(!('cards' in this)) this.cards=[];
} }
sameSuitAs(card){ sameSuitAs(card){
return get.suit(this)==get.suit(card); return get.suit(this)==get.suit(card);
@ -31545,7 +31543,6 @@
return this; return this;
} }
/** /**
* @throws {'Do not call this method'}
* @returns {never} * @returns {never}
*/ */
typeAnnotation(){ typeAnnotation(){
@ -31621,7 +31618,7 @@
* @type {boolean} * @type {boolean}
*/ */
this.unreal; this.unreal;
throw 'Do not call this method'; throw new Error('Do not call this method');
} }
}, },
Dialog:class extends HTMLDivElement{ Dialog:class extends HTMLDivElement{
@ -32907,7 +32904,7 @@
}, },
directHit_ai:true, directHit_ai:true,
skillTagFilter:(player,tag,arg)=>{ skillTagFilter:(player,tag,arg)=>{
const card=arg.card; const card=get.autoViewAs(arg.card);
if(card.name!='sha'||!card.storage.stratagem_buffed) return false; if(card.name!='sha'||!card.storage.stratagem_buffed) return false;
const target=arg.target; const target=arg.target;
if(target.countCards('h','shan')>=1&&!target.storage.stratagem_fury) return false; if(target.countCards('h','shan')>=1&&!target.storage.stratagem_fury) return false;
@ -42237,10 +42234,13 @@
} }
}); });
}, },
updateRoundNumber:()=>game.broadcastAll((num1,num2,top)=>{ updateRoundNumber:()=>{
if(ui.cardPileNumber) ui.cardPileNumber.innerHTML=`${num1}轮 剩余牌: ${num2}`; game.broadcastAll((roundNumber,pileTop)=>{
_status.pileTop=top; if(game.roundNumber!=roundNumber) game.roundNumber=roundNumber;
},game.roundNumber,ui.cardPile.childNodes.length,ui.cardPile.firstChild), if(_status.pileTop!=pileTop) _status.pileTop=pileTop;
},game.roundNumber,ui.cardPile.firstChild);
ui.updateRoundNumber();
},
asyncDraw:(players,num,drawDeck,bottom)=>players.forEach((value,index)=>{ asyncDraw:(players,num,drawDeck,bottom)=>players.forEach((value,index)=>{
let num2=1; let num2=1;
if(typeof num=='number') num2=num; if(typeof num=='number') num2=num;
@ -52133,7 +52133,7 @@
} }
ui.arena.setNumber=function(num){ ui.arena.setNumber=function(num){
this.dataset.number=num; this.dataset.number=num;
ui.create.playerPositions(); ui.updatePlayerPositions();
// if(game.layout=='nova'&&parseInt(num)<7){ // if(game.layout=='nova'&&parseInt(num)<7){
// ui.arena.classList.add('player_autolong'); // ui.arena.classList.add('player_autolong');
// } // }
@ -53102,48 +53102,8 @@
} }
}, },
player:(position,noclick)=>new lib.element.Player(position,noclick), player:(position,noclick)=>new lib.element.Player(position,noclick),
/**
* @author curpond
* @author Tipx-L
* @param {number} [numberOfPlayers]
*/
connectPlayerPositions:numberOfPlayers=>{
if(typeof numberOfPlayers!='number') numberOfPlayers=lib.configOL.number;
if(!numberOfPlayers) return;
const playerPositions=ui.playerPositions;
while(playerPositions.length){
playerPositions.pop().remove();
}
const temporaryPlayer=ui.create.div('.player.connect',ui.window).hide();
const computedStyle=getComputedStyle(temporaryPlayer);
const halfWidth=parseFloat(computedStyle.width)/2;
const halfHeight=parseFloat(computedStyle.height)/2;
temporaryPlayer.remove();
const halfNumberOfPlayers=Math.round(numberOfPlayers/2);
const upperPercentage=100/(halfNumberOfPlayers+1);
const scale=10/numberOfPlayers;
for(let ordinal=0;ordinal<halfNumberOfPlayers;ordinal++){
playerPositions.push(lib.init.sheet([
`#window>.player.connect[data-position='${ordinal}']{`,
`left:calc(${upperPercentage*(ordinal+1)}% - ${halfWidth}px);`,
`top:calc(${100/3}% - ${halfHeight}px);`,
scale<1?`transform:scale(${scale});`:'',
'}'
].join('')));
}
const lowerPercentage=100/(numberOfPlayers-halfNumberOfPlayers+1);
for(let ordinal=halfNumberOfPlayers;ordinal<numberOfPlayers;ordinal++){
playerPositions.push(lib.init.sheet([
`#window>.player.connect[data-position='${ordinal}']{`,
`left:calc(${lowerPercentage*(ordinal-halfNumberOfPlayers+1)}% - ${halfWidth}px);`,
`top:calc(${100*2/3}% - ${halfHeight}px);`,
scale<1?`transform:scale(${scale});`:'',
'}'
].join('')));
}
},
connectPlayers:ip=>{ connectPlayers:ip=>{
ui.create.connectPlayerPositions(); ui.updateConnectPlayerPositions();
game.connectPlayers=[]; game.connectPlayers=[];
const numberOfPlayers=lib.configOL.number; const numberOfPlayers=lib.configOL.number;
for(let position=0;position<numberOfPlayers;position++){ for(let position=0;position<numberOfPlayers;position++){
@ -53198,44 +53158,6 @@
ui.connectStartButton=button; ui.connectStartButton=button;
ui.connectStartBar=bar; ui.connectStartBar=bar;
}, },
/**
* @author curpond
* @author Tipx-L
* @param {number} [numberOfPlayers]
*/
playerPositions:numberOfPlayers=>{
if(typeof numberOfPlayers!='number') numberOfPlayers=ui.arena.dataset.number;
//当人数小于8时还是用以前的布局。
if(!numberOfPlayers||numberOfPlayers<9) return;
const playerPositions=ui.playerPositions;
while(playerPositions.length){
playerPositions.pop().remove();
}
//单个人物的宽度。这里要设置玩家的实际的宽度
const temporaryPlayer=ui.create.div('.player',ui.arena).hide();
const computedStyle=getComputedStyle(temporaryPlayer);
const scale=6/numberOfPlayers;
//玩家顶部距离父容器上边缘的距离偏移的单位距离
const quarterHeight=parseFloat(computedStyle.height)/4*scale;
const halfWidth=parseFloat(computedStyle.width)/2;
temporaryPlayer.remove();
//列数即假如8人场除去自己后上面7个人占7列
const columnCount=numberOfPlayers-1;
const percentage=90/(columnCount-1);
//仅当游戏人数大于8人且玩家的座位号大于0时设置玩家的位置。因为0号位是game.me在最下方无需设置。
for(let ordinal=1;ordinal<numberOfPlayers;ordinal++){
const reversedOrdinal=columnCount-ordinal;
//动态计算玩家的top属性实现拱桥的效果。只让两边的各两个人向下偏移一些
const top=Math.max(0,Math.round(numberOfPlayers/5)-Math.min(Math.abs(ordinal-1),Math.abs(reversedOrdinal)))*quarterHeight;
playerPositions.push(lib.init.sheet([
`#arena[data-number='${numberOfPlayers}']>.player[data-position='${ordinal}']{`,
`left:calc(${percentage*reversedOrdinal+5}% - ${halfWidth}px);`,
`top:${top}px;`,
`transform:scale(${scale});`,
'}'
].join('')));
}
},
players:numberOfPlayers=>{ players:numberOfPlayers=>{
if(numberOfPlayers===0){ if(numberOfPlayers===0){
return; return;
@ -56235,22 +56157,21 @@
const skillInformation=get.info(gameEvent.skill),viewAs=skillInformation.viewAs; const skillInformation=get.info(gameEvent.skill),viewAs=skillInformation.viewAs;
if(typeof viewAs=='function'){ if(typeof viewAs=='function'){
const viewedAs=viewAs(result.cards,gameEvent.player); const viewedAs=viewAs(result.cards,gameEvent.player);
if(viewedAs){ if(viewedAs) result.card=get.autoViewAs(viewedAs);
viewedAs.cards=result.cards; }
result.card=get.autoViewAs(viewedAs); else if(viewAs) result.card=get.autoViewAs(viewAs);
const resultCard=result.card;
if(resultCard){
const cards=result.cards;
if(cards.length==1){
const firstCard=cards[0];
if(!resultCard.suit) resultCard.suit=get.suit(firstCard);
if(!resultCard.number) resultCard.number=get.number(firstCard);
} }
} }
else if(viewAs){ const skillDialog=gameEvent.skillDialog;
viewAs.cards=result.cards; if(skillDialog&&get.objtype(skillDialog)=='div') skillDialog.close();
result.card=get.autoViewAs(viewAs); gameEvent.player.getCards('hej').forEach(card=>card.recheck('useSkill'));
}
if(gameEvent.skillDialog&&get.objtype(gameEvent.skillDialog)=='div'){
gameEvent.skillDialog.close();
}
var cards=gameEvent.player.getCards('hej');
for(var i=0;i<cards.length;i++){
cards[i].recheck('useSkill');
}
gameEvent.restore(); gameEvent.restore();
} }
else if(['chooseToUse','chooseToRespond'].includes(gameEvent.name)) result.card=get.autoViewAs(result.cards[0]); else if(['chooseToUse','chooseToRespond'].includes(gameEvent.name)) result.card=get.autoViewAs(result.cards[0]);
@ -57932,6 +57853,87 @@
} }
ui._recycle[key]=node; ui._recycle[key]=node;
}, },
/**
* @author curpond
* @author Tipx-L
* @param {number} [numberOfPlayers]
*/
updateConnectPlayerPositions:numberOfPlayers=>{
if(typeof numberOfPlayers!='number') numberOfPlayers=lib.configOL.number;
if(!numberOfPlayers) return;
const playerPositions=ui.playerPositions;
while(playerPositions.length){
playerPositions.pop().remove();
}
const temporaryPlayer=ui.create.div('.player.connect',ui.window).hide();
const computedStyle=getComputedStyle(temporaryPlayer);
const halfWidth=parseFloat(computedStyle.width)/2;
const halfHeight=parseFloat(computedStyle.height)/2;
temporaryPlayer.remove();
const halfNumberOfPlayers=Math.round(numberOfPlayers/2);
const upperPercentage=100/(halfNumberOfPlayers+1);
const scale=10/numberOfPlayers;
for(let ordinal=0;ordinal<halfNumberOfPlayers;ordinal++){
playerPositions.push(lib.init.sheet([
`#window>.player.connect[data-position='${ordinal}']{`,
`left:calc(${upperPercentage*(ordinal+1)}% - ${halfWidth}px);`,
`top:calc(${100/3}% - ${halfHeight}px);`,
scale<1?`transform:scale(${scale});`:'',
'}'
].join('')));
}
const lowerPercentage=100/(numberOfPlayers-halfNumberOfPlayers+1);
for(let ordinal=halfNumberOfPlayers;ordinal<numberOfPlayers;ordinal++){
playerPositions.push(lib.init.sheet([
`#window>.player.connect[data-position='${ordinal}']{`,
`left:calc(${lowerPercentage*(ordinal-halfNumberOfPlayers+1)}% - ${halfWidth}px);`,
`top:calc(${100*2/3}% - ${halfHeight}px);`,
scale<1?`transform:scale(${scale});`:'',
'}'
].join('')));
}
},
/**
* @author curpond
* @author Tipx-L
* @param {number} [numberOfPlayers]
*/
updatePlayerPositions:numberOfPlayers=>{
if(typeof numberOfPlayers!='number') numberOfPlayers=ui.arena.dataset.number;
//当人数小于8时还是用以前的布局。
if(!numberOfPlayers||numberOfPlayers<9) return;
const playerPositions=ui.playerPositions;
while(playerPositions.length){
playerPositions.pop().remove();
}
//单个人物的宽度。这里要设置玩家的实际的宽度
const temporaryPlayer=ui.create.div('.player',ui.arena).hide();
const computedStyle=getComputedStyle(temporaryPlayer);
const scale=6/numberOfPlayers;
//玩家顶部距离父容器上边缘的距离偏移的单位距离
const quarterHeight=parseFloat(computedStyle.height)/4*scale;
const halfWidth=parseFloat(computedStyle.width)/2;
temporaryPlayer.remove();
//列数即假如8人场除去自己后上面7个人占7列
const columnCount=numberOfPlayers-1;
const percentage=90/(columnCount-1);
//仅当游戏人数大于8人且玩家的座位号大于0时设置玩家的位置。因为0号位是game.me在最下方无需设置。
for(let ordinal=1;ordinal<numberOfPlayers;ordinal++){
const reversedOrdinal=columnCount-ordinal;
//动态计算玩家的top属性实现拱桥的效果。只让两边的各两个人向下偏移一些
const top=Math.max(0,Math.round(numberOfPlayers/5)-Math.min(Math.abs(ordinal-1),Math.abs(reversedOrdinal)))*quarterHeight;
playerPositions.push(lib.init.sheet([
`#arena[data-number='${numberOfPlayers}']>.player[data-position='${ordinal}']{`,
`left:calc(${percentage*reversedOrdinal+5}% - ${halfWidth}px);`,
`top:${top}px;`,
`transform:scale(${scale});`,
'}'
].join('')));
}
},
updateRoundNumber:()=>game.broadcastAll((roundNumber,cardPileNumber)=>{
if(ui.cardPileNumber) ui.cardPileNumber.innerHTML=`${roundNumber}轮 剩余牌: ${cardPileNumber}`;
},game.roundNumber,ui.cardPile.childElementCount)
}; };
const get={ const get={
/** /**
@ -62649,7 +62651,7 @@
} }
} }
}, },
get get:get
}; };
/** /**
* @template T * @template T

View File

@ -5041,6 +5041,13 @@ div[data-decoration="bronze"]::after{
border-radius: 16px; border-radius: 16px;
} }
.loading-screen {
background-color: black;
height: 100%;
width: 100%;
z-index: 31415926;
}
/*--------动画--------*/ /*--------动画--------*/
@keyframes shadow_thunder { @keyframes shadow_thunder {
0% { 0% {
@ -5542,6 +5549,24 @@ div[data-decoration="bronze"]::after{
background-position: left center; background-position: left center;
} }
} }
@keyframes opacity-0-1 {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes opacity-1-0 {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
/*--------其它--------*/ /*--------其它--------*/
::-webkit-scrollbar { ::-webkit-scrollbar {
display: none; display: none;