Finish the constructor of VCard.

This commit is contained in:
Tipx-L 2023-10-15 02:31:30 -07:00
parent b5c704264c
commit 7af2244485
1 changed files with 115 additions and 79 deletions

View File

@ -1,5 +1,12 @@
"use strict"; "use strict";
{ {
/**
* @typedef {InstanceType<typeof lib.element.Player>} Player
* @typedef {InstanceType<typeof lib.element.Card>} Card
* @typedef {InstanceType<typeof lib.element.VCard>} VCard
* @typedef {InstanceType<typeof lib.element.Event>} GameEvent
* @typedef {InstanceType<typeof lib.element.NodeWS>} NodeWS
*/
const userAgent=navigator.userAgent.toLowerCase(); const userAgent=navigator.userAgent.toLowerCase();
if(!localStorage.getItem('gplv3_noname_alerted')){ if(!localStorage.getItem('gplv3_noname_alerted')){
if(confirm('①无名杀是一款基于GPLv3协议的开源软件\n你可以在遵守GPLv3协议的基础上任意使用修改并转发《无名杀》以及所有基于《无名杀》开发的拓展。\n点击“确定”即代表您认可并接受GPLv3协议↓\nhttps://www.gnu.org/licenses/gpl-3.0.html\n②无名杀官方发布地址仅有GitHub仓库\n其他所有的所谓“无名杀”社群包括但不限于绝大多数“官方”QQ群、QQ频道等均为玩家自发组织与无名杀官方无关')){ if(confirm('①无名杀是一款基于GPLv3协议的开源软件\n你可以在遵守GPLv3协议的基础上任意使用修改并转发《无名杀》以及所有基于《无名杀》开发的拓展。\n点击“确定”即代表您认可并接受GPLv3协议↓\nhttps://www.gnu.org/licenses/gpl-3.0.html\n②无名杀官方发布地址仅有GitHub仓库\n其他所有的所谓“无名杀”社群包括但不限于绝大多数“官方”QQ群、QQ频道等均为玩家自发组织与无名杀官方无关')){
@ -78,7 +85,7 @@
clicked:false, clicked:false,
auto:false, auto:false,
/** /**
* @type {InstanceType<typeof lib.element.Event>} * @type {GameEvent}
*/ */
event:null, event:null,
ai:{}, ai:{},
@ -20467,6 +20474,9 @@
* @param {true} [noclick] * @param {true} [noclick]
*/ */
constructor(position,noclick){ constructor(position,noclick){
/**
* @type {Player}
*/
const player=ui.create.div('.player',position); const player=ui.create.div('.player',position);
Object.setPrototypeOf(player,lib.element.Player.prototype); Object.setPrototypeOf(player,lib.element.Player.prototype);
const node=player.node={ const node=player.node={
@ -29760,6 +29770,14 @@
hasGaintag(tag){ hasGaintag(tag){
return this.gaintag&&this.gaintag.contains(tag); return this.gaintag&&this.gaintag.contains(tag);
} }
/**
* @param {[string, number, string, string] | {
* suit: string;
* number: number;
* name: string;
* nature: string;
* }} card
*/
init(card){ init(card){
if(Array.isArray(card)){ if(Array.isArray(card)){
if(card[2]=='huosha'){ if(card[2]=='huosha'){
@ -30299,36 +30317,65 @@
}, },
VCard:class{ VCard:class{
/** /**
* @param {string | [string, number, string, string] | { * @param {string | [string, number, string, string] | Card | Record<string, string | number | boolean | any[]>} [suitOrCard]
* suit: string; * @param {number | Card[]} [numberOrCards]
* number: number;
* name: string;
* nature: string;
* }} suitOrTupleOrStruct
* @param {number} [number]
* @param {string} [name] * @param {string} [name]
* @param {string} [nature] * @param {string} [nature]
*/ */
constructor(suitOrTupleOrStruct,number,name,nature){ constructor(suitOrCard,numberOrCards,name,nature){
if(Array.isArray(suitOrTupleOrStruct)){ if(typeof suitOrCard=='undefined'&&typeof numberOrCards=='undefined'&&typeof name=='undefined'&&typeof nature=='undefined') return;
this.suit=suitOrTupleOrStruct[0]; if(Array.isArray(suitOrCard)){
this.number=suitOrTupleOrStruct[1]; this.suit=suitOrCard[0];
this.name=suitOrTupleOrStruct[2]; this.number=suitOrCard[1];
this.nature=suitOrTupleOrStruct[3]; this.name=suitOrCard[2];
this.nature=suitOrCard[3];
} }
else if(typeof suitOrTupleOrStruct=='object'){ else if(suitOrCard instanceof lib.element.Card){
this.suit=suitOrTupleOrStruct.suit; this.name=get.name(suitOrCard);
this.number=suitOrTupleOrStruct.number; this.suit=get.suit(suitOrCard);
this.name=suitOrTupleOrStruct.name; this.color=get.color(suitOrCard);
this.nature=suitOrTupleOrStruct.nature; this.number=get.number(suitOrCard);
this.nature=get.nature(suitOrCard);
this.isCard=true;
this.cardid=suitOrCard.cardid;
this.wunature=suitOrCard.wunature;
this.storage=get.copy(suitOrCard.storage);
if(Array.isArray(numberOrCards)) this.cards=numberOrCards.slice();
else this.cards=[suitOrCard];
} }
else{ else if(typeof suitOrCard!='string'){
this.suit=suitOrTupleOrStruct; Object.keys(suitOrCard).forEach(key=>{
this.number=number; const propertyDescriptor=Object.getOwnPropertyDescriptor(suitOrCard,key),value=propertyDescriptor.value;
this.name=name; if(Array.isArray(value)) this[key]=value.slice();
this.nature=nature; else Object.defineProperty(this,key,propertyDescriptor);
});
if(Array.isArray(numberOrCards)){
const noCards=!this.hasOwnProperty('cards');
this.cards=numberOrCards.slice();
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);
if(!this.hasOwnProperty('number')) this.number=get.number(this);
if(!this.hasOwnProperty('nature')) this.nature=get.nature(this);
}
}
} }
this.color=get.color(); if(typeof suitOrCard=='string') this.suit=suitOrCard;
if(typeof numberOrCards=='number') this.number=numberOrCards;
if(typeof name=='string') this.name=name;
if(typeof nature=='string') this.nature=nature;
if(this.hasOwnProperty('suit')&&!this.hasOwnProperty('color')) this.color=get.color(this);
if(!this.hasOwnProperty('storage'))
/**
* @type {Record<string, any>}
*/
this.storage={};
if(!this.hasOwnProperty('cards'))
/**
* @type {Card[]}
*/
this.cards=[];
const info=get.info(this,false);
} }
}, },
Button:class extends HTMLDivElement{ Button:class extends HTMLDivElement{
@ -31406,7 +31453,7 @@
}, },
Client:class{ Client:class{
/** /**
* @param {InstanceType<typeof lib.element.NodeWS | typeof import('ws').WebSocket>} ws * @param {NodeWS | InstanceType<typeof import('ws').WebSocket>} ws
*/ */
constructor(ws){ constructor(ws){
this.ws=ws; this.ws=ws;
@ -42405,11 +42452,11 @@
}); });
}, },
/** /**
* @type {InstanceType<typeof lib.element.Player>[]} * @type {Player[]}
*/ */
players:[], players:[],
/** /**
* @type {InstanceType<typeof lib.element.Player>[]} * @type {Player[]}
*/ */
dead:[], dead:[],
imported:[], imported:[],
@ -57474,44 +57521,7 @@
} }
} }
}, },
autoViewAs:(card,cards)=>{ autoViewAs:(card,cards)=>new lib.element.VCard(card,cards),
let _card;
if(get.itemtype(card)=='card'){
_card={
name:get.name(card),
suit:get.suit(card),
color:get.color(card),
number:get.number(card),
nature:get.nature(card),
isCard:true,
cardid:card.cardid,
wunature:card.wunature,
storage:get.copy(card.storage),
};
if(Array.isArray(cards)) _card.cards=cards.slice(0);
else _card.cards=[card];
}
else{
_card=get.copy(card);
if(Array.isArray(cards)){
if(_card.cards){
_card.cards=cards.slice(0);
}
else{
_card.cards=cards.slice(0);
if(!lib.suits.includes(_card.suit)) _card.suit=get.suit(_card);
if(!Object.keys(lib.color).includes(_card.color)) _card.color=get.color(_card);
if(!_card.hasOwnProperty('number')) _card.number=get.number(_card);
if(!_card.hasOwnProperty('nature')) _card.nature=(get.nature(_card)||false);
}
}
}
const info=get.info(_card,false);
if(info.autoViewAs){
_card.name=info.autoViewAs;
}
return _card;
},
/** /**
* @deprecated * @deprecated
*/ */
@ -58652,6 +58662,12 @@
if(subtype.startsWith('equip')) return parseInt(subtype[5]); if(subtype.startsWith('equip')) return parseInt(subtype[5]);
return 0; return 0;
}, },
/**
*
* @param {Card | VCard} card
* @param {false | Player} [player]
* @returns {string}
*/
name:(card,player)=>{ name:(card,player)=>{
if(get.itemtype(player)=='player'||(player!==false&&get.position(card)=='h')){ if(get.itemtype(player)=='player'||(player!==false&&get.position(card)=='h')){
var owner=player||get.owner(card); var owner=player||get.owner(card);
@ -58661,6 +58677,11 @@
} }
return card.name; return card.name;
}, },
/**
* @param {Card | VCard | Card[] | VCard[]} card
* @param {false | Player} [player]
* @returns {string}
*/
suit:(card,player)=>{ suit:(card,player)=>{
if(!card) return; if(!card) return;
if(Array.isArray(card)){ if(Array.isArray(card)){
@ -58682,17 +58703,17 @@
} }
}, },
/** /**
* @param {*} card * @param {Card | VCard | Card[] | VCard[]} card
* @param {InstanceType<typeof lib.element.Player>} player * @param {false | Player} [player]
* @returns {keyof typeof lib.color} * @returns {string}
*/ */
color:(card,player)=>{ color:(card,player)=>{
if(!card) return; if(!card) return;
if(Array.isArray(card)){ if(Array.isArray(card)){
if(!card.length) return 'none'; if(!card.length) return 'none';
const color=get.color(card[0],player); const cards=card.slice(),color=get.color(cards.shift(),player);
for(let i=1;i<card.length;i++){ for(const anotherCard of cards){
if(get.color(card[i],player)!=color) return 'none'; if(get.color(anotherCard,player)!=color) return 'none';
} }
return color; return color;
} }
@ -58704,12 +58725,17 @@
} }
else{ else{
const suit=get.suit(card,player); const suit=get.suit(card,player);
for(let i in lib.color){ for(const entry of Object.entries(lib.color)){
if(lib.color[i].includes(suit)) return i; if(entry[1].includes(suit)) return entry[0];
} }
return 'none'; return 'none';
} }
}, },
/**
* @param {Card | VCard} card
* @param {false | Player} [player]
* @returns {number}
*/
number:(card,player)=>{ number:(card,player)=>{
if(!card) return; if(!card) return;
//狗卡你是真敢出啊 //狗卡你是真敢出啊
@ -58729,12 +58755,17 @@
} }
return number; return number;
}, },
//返回一张杀的属性。如有多种属性则用 lib.natureSeparator 分割开来。例:火雷【杀】的返回值为 fire|thunder /**
* 返回一张杀的属性如有多种属性则用`lib.natureSeparator`分割开来火雷的返回值为`fire|thunder`
* @param {string | string[] | Card | VCard} card
* @param {false | Player} [player]
* @returns {string}
*/
nature:(card,player)=>{ nature:(card,player)=>{
if(typeof card=='string') return card.split(lib.natureSeparator).sort(lib.sort.nature).join(lib.natureSeparator); if(typeof card=='string') return card.split(lib.natureSeparator).sort(lib.sort.nature).join(lib.natureSeparator);
if(Array.isArray(card)) return card.sort(lib.sort.nature).join(lib.natureSeparator); if(Array.isArray(card)) return card.sort(lib.sort.nature).join(lib.natureSeparator);
var nature=card.nature; var nature=card.nature;
if(get.itemtype(player)=='player'||player!==false){ if(player instanceof lib.element.Player||player!==false){
var owner=get.owner(card); var owner=get.owner(card);
if(owner){ if(owner){
return game.checkMod(card,owner,nature,'cardnature',owner); return game.checkMod(card,owner,nature,'cardnature',owner);
@ -58742,12 +58773,17 @@
} }
return nature; return nature;
}, },
//返回包含所有属性的数组 /**
natureList(card,player){ * 返回包含所有属性的数组
* @param {string[] | string} card
* @param {false | Player} [player]
* @returns {string[]}
*/
natureList:(card,player)=>{
if(!card) return []; if(!card) return [];
if(get.itemtype(card)=='natures') return card.split(lib.natureSeparator); if(get.itemtype(card)=='natures') return card.split(lib.natureSeparator);
if(get.itemtype(card)=='nature') return [card]; if(get.itemtype(card)=='nature') return [card];
var natures=get.nature.apply(this,arguments); const natures=get.nature(card,player);
if(typeof natures!='string') return []; if(typeof natures!='string') return [];
return natures.split(lib.natureSeparator); return natures.split(lib.natureSeparator);
}, },