Merge pull request #1102 from nofficalfs/Dev-Feat-HookTension
对`lib.hooks`的调整,以及准备增加`lib.assembly`
This commit is contained in:
commit
32920c5f09
|
@ -1,3 +1,5 @@
|
||||||
|
import { NonameAnnounceType } from "./interface.d.ts"
|
||||||
|
|
||||||
export interface IAnnounceSubscriber {
|
export interface IAnnounceSubscriber {
|
||||||
subscribe(name: string): void;
|
subscribe(name: string): void;
|
||||||
unsubscribe(name: string): void;
|
unsubscribe(name: string): void;
|
||||||
|
@ -21,7 +23,7 @@ export class Announce {
|
||||||
* @param name - 要推送事件的名称
|
* @param name - 要推送事件的名称
|
||||||
* @param values - 要推送的数据
|
* @param values - 要推送的数据
|
||||||
*/
|
*/
|
||||||
publish<T>(name: string, values: T): T
|
publish<Type extends NonameAnnounceType, Name extends keyof Type>(name: Name, values: Parameters<Type[Name]>[0]): Parameters<Type[Name]>[0]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订阅给定名字的事件,并返回给定的函数
|
* 订阅给定名字的事件,并返回给定的函数
|
||||||
|
@ -33,7 +35,7 @@ export class Announce {
|
||||||
* @param name - 要订阅事件的名称
|
* @param name - 要订阅事件的名称
|
||||||
* @param method - 事件触发时执行的函数
|
* @param method - 事件触发时执行的函数
|
||||||
*/
|
*/
|
||||||
subscribe<T>(name: string, method: (values: T) => void): (values: T) => void
|
subscribe<Type extends NonameAnnounceType, Name extends keyof Type>(name: Name, method: Type[Name]): Type[Name]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消指定事件某一个函数的订阅,并返回该函数
|
* 取消指定事件某一个函数的订阅,并返回该函数
|
||||||
|
@ -43,7 +45,7 @@ export class Announce {
|
||||||
* @param name - 要取消订阅事件的名称
|
* @param name - 要取消订阅事件的名称
|
||||||
* @param method - 订阅指定事件的函数
|
* @param method - 订阅指定事件的函数
|
||||||
*/
|
*/
|
||||||
unsubscribe<T>(name: string, method: (values: T) => void): (values: T) => void
|
unsubscribe<Type extends NonameAnnounceType, Name extends keyof Type>(name: Name, method: Type[Name]): Type[Name]
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AnnounceSubscriber<T> implements IAnnounceSubscriber {
|
export class AnnounceSubscriber<T> implements IAnnounceSubscriber {
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
|
||||||
|
export interface NonameAnnounceType {
|
||||||
|
// Apperaence 外观区域
|
||||||
|
// 用于关于无名杀外观方面的通知
|
||||||
|
|
||||||
|
// Apperaence.Theme 无名杀主题区域
|
||||||
|
/**
|
||||||
|
* 主题正在被切换时通知
|
||||||
|
*
|
||||||
|
* @param values - 主题名称
|
||||||
|
*/
|
||||||
|
"Noname.Apperaence.Theme.onChanging": AnnounceFunction<string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主题被切换时通知
|
||||||
|
*
|
||||||
|
* @param values - 主题名称
|
||||||
|
*/
|
||||||
|
"Noname.Apperaence.Theme.onChanged": AnnounceFunction<string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主题被切换时,已经显示完毕后通知
|
||||||
|
*
|
||||||
|
* @param values - 主题名称
|
||||||
|
*/
|
||||||
|
"Noname.Apperaence.Theme.onChangeFinished": AnnounceFunction<string>
|
||||||
|
|
||||||
|
// Game 游戏区域
|
||||||
|
// 包含游戏对局下的通知
|
||||||
|
|
||||||
|
// Game.Event 事件区域
|
||||||
|
/**
|
||||||
|
* 当游戏对局开始时进行通知
|
||||||
|
*
|
||||||
|
* @param values - 空对象
|
||||||
|
*/
|
||||||
|
"Noname.Game.Event.GameStart": AnnounceFunction<{}>
|
||||||
|
|
||||||
|
|
||||||
|
// Init 初始化区域
|
||||||
|
// 用于关于初始化方面的通知
|
||||||
|
|
||||||
|
// Init.Extension 扩展初始化区域
|
||||||
|
/**
|
||||||
|
* 当扩展初始化完成时通知
|
||||||
|
*
|
||||||
|
* @param values - 扩展名称
|
||||||
|
*/
|
||||||
|
"Noname.Init.Extension.onLoad": AnnounceFunction<string>
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AnnounceFunction<T> = (values: T) => void
|
|
@ -0,0 +1,110 @@
|
||||||
|
import { lib } from "../index.js"
|
||||||
|
import { ui } from "../../ui/index.js"
|
||||||
|
import { get } from "../../get/index.js"
|
||||||
|
import { _status } from "../../status/index.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import("./interface.js").NonameAssemblyType["checkBegin"])}
|
||||||
|
*/
|
||||||
|
export const checkBegin = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import("./interface.js").NonameAssemblyType["checkCard"])}
|
||||||
|
*/
|
||||||
|
export const checkCard = {
|
||||||
|
updateTempname(card, event) {
|
||||||
|
if (lib.config.cardtempname === 'off') return
|
||||||
|
if (get.name(card) === card.name && get.is.sameNature(get.nature(card), card.nature, true)) return
|
||||||
|
const node = ui.create.cardTempName(card)
|
||||||
|
if (lib.config.cardtempname !== 'default') node.classList.remove('vertical')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import("./interface.js").NonameAssemblyType["checkTarget"])}
|
||||||
|
*/
|
||||||
|
export const checkTarget = {
|
||||||
|
updateInstance(target, event) {
|
||||||
|
// @ts-ignore
|
||||||
|
if (!target.instance) return;
|
||||||
|
['selected', 'selectable'].forEach(className => {
|
||||||
|
if (target.classList.contains(className)) {
|
||||||
|
// @ts-ignore
|
||||||
|
target.instance.classList.add(className)
|
||||||
|
} else {
|
||||||
|
// @ts-ignore
|
||||||
|
target.instance.classList.remove(className)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import("./interface.js").NonameAssemblyType["checkButton"])}
|
||||||
|
*/
|
||||||
|
export const checkButton = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import("./interface.js").NonameAssemblyType["checkEnd"])}
|
||||||
|
*/
|
||||||
|
export const checkEnd = {
|
||||||
|
autoConfirm(event, { ok, auto, autoConfirm }) {
|
||||||
|
if (!event.isMine()) return
|
||||||
|
const skillinfo = get.info(event.skill) || {}
|
||||||
|
if (ok && auto && (autoConfirm || skillinfo.direct) && !_status.touchnocheck
|
||||||
|
&& !_status.mousedown && (!_status.mousedragging || !_status.mouseleft)) {
|
||||||
|
if (ui.confirm) ui.confirm.close()
|
||||||
|
// @ts-ignore
|
||||||
|
if (event.skillDialog === true) event.skillDialog = false
|
||||||
|
ui.click.ok()
|
||||||
|
_status.mousedragging = null
|
||||||
|
if (skillinfo.preservecancel) ui.create.confirm('c')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import("./interface.js").NonameAssemblyType["uncheckBegin"])}
|
||||||
|
*/
|
||||||
|
export const uncheckBegin = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import("./interface.js").NonameAssemblyType["uncheckCard"])}
|
||||||
|
*/
|
||||||
|
export const uncheckCard = {
|
||||||
|
removeTempname(card, event) {
|
||||||
|
// @ts-ignore
|
||||||
|
if (!card._tempName) return
|
||||||
|
// @ts-ignore
|
||||||
|
card._tempName.delete()
|
||||||
|
// @ts-ignore
|
||||||
|
delete card._tempName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import("./interface.js").NonameAssemblyType["uncheckTarget"])}
|
||||||
|
*/
|
||||||
|
export const uncheckTarget = {
|
||||||
|
removeInstance(target, event) {
|
||||||
|
// @ts-ignore
|
||||||
|
if (!target.instance) return
|
||||||
|
// @ts-ignore
|
||||||
|
target.instance.classList.remove('selected')
|
||||||
|
// @ts-ignore
|
||||||
|
target.instance.classList.remove('selectable')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import("./interface.js").NonameAssemblyType["uncheckButton"])}
|
||||||
|
*/
|
||||||
|
export const uncheckButton = {}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(import("./interface.js").NonameAssemblyType["uncheckEnd"])}
|
||||||
|
*/
|
||||||
|
export const uncheckEnd = {}
|
|
@ -0,0 +1,134 @@
|
||||||
|
import * as buildin from "./buildin.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* > 这玩意因为狂神还得是数组
|
||||||
|
*
|
||||||
|
* @template {import("./interface.d.ts").NonameAssemblyType} AssemblyType
|
||||||
|
* @template {keyof AssemblyType} Name
|
||||||
|
* @extends {Array<AssemblyType[Name][keyof AssemblyType[Name]]>}
|
||||||
|
*/
|
||||||
|
export class NonameAssembly extends Array {
|
||||||
|
/**
|
||||||
|
* @type {Name}
|
||||||
|
*/
|
||||||
|
#name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Map<keyof AssemblyType[Name], number>}
|
||||||
|
*/
|
||||||
|
#record
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Name} name
|
||||||
|
*/
|
||||||
|
constructor(name) {
|
||||||
|
super()
|
||||||
|
this.#name = name
|
||||||
|
this.#record = new Map()
|
||||||
|
|
||||||
|
if (name in buildin) {
|
||||||
|
// @ts-ignore
|
||||||
|
for (const [key, item] of Object.entries(buildin[name])) {
|
||||||
|
// @ts-ignore
|
||||||
|
this.add(key, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get [Symbol.species]() {
|
||||||
|
return Array
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this.#name
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {keyof AssemblyType[Name]} name
|
||||||
|
* @param {AssemblyType[Name][keyof AssemblyType[Name]]} content
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
// @ts-ignore
|
||||||
|
add(name, content) {
|
||||||
|
if (!content) {
|
||||||
|
// @ts-expect-error A
|
||||||
|
content = name
|
||||||
|
// @ts-expect-error A
|
||||||
|
name = content.name
|
||||||
|
}
|
||||||
|
if (typeof content !== "function") throw new Error("you can't add a non-function to assembly.")
|
||||||
|
if (typeof name !== "string" || name.length === 0) throw new Error("you can't add a anonymous function to assembly.")
|
||||||
|
|
||||||
|
if (!this.has(name)) {
|
||||||
|
this.#record.set(name, this.length)
|
||||||
|
Array.prototype.push.call(this, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {keyof AssemblyType[Name]} name
|
||||||
|
* @param {AssemblyType[Name][keyof AssemblyType[Name]]} content
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
// @ts-ignore
|
||||||
|
push(name, content) {
|
||||||
|
return this.add(name, content).length
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {keyof AssemblyType[Name]} name
|
||||||
|
*/
|
||||||
|
has(name) {
|
||||||
|
return this.#record.has(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {keyof AssemblyType[Name]} name
|
||||||
|
* @returns {AssemblyType[Name][keyof AssemblyType[Name]] | undefined}
|
||||||
|
*/
|
||||||
|
get(name) {
|
||||||
|
if (!this.has(name)) return void 0
|
||||||
|
// @ts-ignore
|
||||||
|
return this[this.#record.get(name)]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {keyof AssemblyType[Name]} name
|
||||||
|
* @param {AssemblyType[Name][keyof AssemblyType[Name]]} content
|
||||||
|
*/
|
||||||
|
update(name, content) {
|
||||||
|
if (!this.has(name)) return false
|
||||||
|
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
this[this.#record.get(name)] = content
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultAssemblys = {
|
||||||
|
checkBegin: new NonameAssembly("checkBegin"),
|
||||||
|
checkCard: new NonameAssembly("checkCard"),
|
||||||
|
checkTarget: new NonameAssembly("checkTarget"),
|
||||||
|
checkButton: new NonameAssembly("checkButton"),
|
||||||
|
checkEnd: new NonameAssembly("checkEnd"),
|
||||||
|
|
||||||
|
uncheckBegin: new NonameAssembly("uncheckBegin"),
|
||||||
|
uncheckCard: new NonameAssembly("uncheckCard"),
|
||||||
|
uncheckTarget: new NonameAssembly("uncheckTarget"),
|
||||||
|
uncheckButton: new NonameAssembly("uncheckButton"),
|
||||||
|
uncheckEnd: new NonameAssembly("uncheckEnd")
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { Button, Card, GameEvent, GameEventPromise, Player } from "../element"
|
||||||
|
|
||||||
|
export interface NonameAssemblyType {
|
||||||
|
checkBegin: {}
|
||||||
|
|
||||||
|
checkCard: {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param card - 检查的卡牌
|
||||||
|
* @param event - 当前检查的事件
|
||||||
|
*/
|
||||||
|
updateTempname(card: Card, event: GameEvent & GameEventPromise): void
|
||||||
|
}
|
||||||
|
|
||||||
|
checkTarget: {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param target - 检查的玩家
|
||||||
|
* @param event - 当前检查的事件
|
||||||
|
*/
|
||||||
|
updateInstance(target: Player, event: GameEvent & GameEventPromise): void
|
||||||
|
}
|
||||||
|
|
||||||
|
checkButton: {}
|
||||||
|
|
||||||
|
checkEnd: {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param event - 当前检查的事件
|
||||||
|
* @param config - 一些配置
|
||||||
|
*/
|
||||||
|
autoConfirm(event: GameEvent & GameEventPromise, config: { ok: boolean, auto: boolean, autoConfirm: boolean }): void
|
||||||
|
}
|
||||||
|
|
||||||
|
uncheckBegin: {}
|
||||||
|
|
||||||
|
uncheckCard: {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param card - 取消检查的卡牌
|
||||||
|
* @param event - 当前检查的事件
|
||||||
|
*/
|
||||||
|
removeTempname(card: Card, event: GameEvent & GameEventPromise): void
|
||||||
|
}
|
||||||
|
|
||||||
|
uncheckTarget: {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param target - 取消检查的玩家
|
||||||
|
* @param event - 当前检查的事件
|
||||||
|
*/
|
||||||
|
removeInstance(target: Player, event: GameEvent & GameEventPromise): void
|
||||||
|
}
|
||||||
|
|
||||||
|
uncheckButton: {}
|
||||||
|
|
||||||
|
uncheckEnd: {}
|
||||||
|
}
|
|
@ -750,6 +750,7 @@ export class GameEvent {
|
||||||
if ((this.name === 'gain' || this.name === 'lose') && !_status.gameDrawed) return;
|
if ((this.name === 'gain' || this.name === 'lose') && !_status.gameDrawed) return;
|
||||||
if (name === 'gameDrawEnd') _status.gameDrawed = true;
|
if (name === 'gameDrawEnd') _status.gameDrawed = true;
|
||||||
if (name === 'gameStart') {
|
if (name === 'gameStart') {
|
||||||
|
lib.announce.publish("Noname.Game.Event.GameStart", {});
|
||||||
lib.announce.publish('gameStart', {});
|
lib.announce.publish('gameStart', {});
|
||||||
if (_status.brawl && _status.brawl.gameStart) _status.brawl.gameStart();
|
if (_status.brawl && _status.brawl.gameStart) _status.brawl.gameStart();
|
||||||
if (lib.config.show_cardpile) ui.cardPileButton.style.display = '';
|
if (lib.config.show_cardpile) ui.cardPileButton.style.display = '';
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
import { lib } from "../index.js"
|
import { lib } from "../index.js"
|
||||||
import { game } from "../../game/index.js"
|
import { game } from "../../game/index.js"
|
||||||
import { ui } from "../../ui/index.js"
|
|
||||||
import { get } from "../../get/index.js"
|
|
||||||
import { _status } from "../../status/index.js"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {(import("./interface.js").NonameHookType["addGroup"])[]}
|
* @type {(import("./interface.js").NonameHookType["addGroup"])[]}
|
||||||
|
@ -213,112 +210,3 @@ export const addNature = [
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import("./interface.js").NonameHookType["checkBegin"])[]}
|
|
||||||
*/
|
|
||||||
export const checkBegin = []
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import("./interface.js").NonameHookType["checkCard"])[]}
|
|
||||||
*/
|
|
||||||
export const checkCard = [
|
|
||||||
function updateTempname(card, event) {
|
|
||||||
if (lib.config.cardtempname === 'off') return
|
|
||||||
if (get.name(card) === card.name && get.is.sameNature(get.nature(card), card.nature, true)) return
|
|
||||||
const node = ui.create.cardTempName(card)
|
|
||||||
if (lib.config.cardtempname !== 'default') node.classList.remove('vertical')
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import("./interface.js").NonameHookType["checkTarget"])[]}
|
|
||||||
*/
|
|
||||||
export const checkTarget = [
|
|
||||||
function updateInstance(target, event) {
|
|
||||||
// @ts-ignore
|
|
||||||
if (!target.instance) return;
|
|
||||||
['selected', 'selectable'].forEach(className => {
|
|
||||||
if (target.classList.contains(className)) {
|
|
||||||
// @ts-ignore
|
|
||||||
target.instance.classList.add(className)
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
target.instance.classList.remove(className)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import("./interface.js").NonameHookType["checkButton"])[]}
|
|
||||||
*/
|
|
||||||
export const checkButton = []
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import("./interface.js").NonameHookType["checkEnd"])[]}
|
|
||||||
*/
|
|
||||||
export const checkEnd = [
|
|
||||||
function autoConfirm(event, { ok, auto, autoConfirm }) {
|
|
||||||
if (!event.isMine()) return
|
|
||||||
const skillinfo = get.info(event.skill) || {}
|
|
||||||
if (ok && auto && (autoConfirm || skillinfo.direct) && !_status.touchnocheck
|
|
||||||
&& !_status.mousedown && (!_status.mousedragging || !_status.mouseleft)) {
|
|
||||||
if (ui.confirm) ui.confirm.close()
|
|
||||||
// @ts-ignore
|
|
||||||
if (event.skillDialog === true) event.skillDialog = false
|
|
||||||
ui.click.ok()
|
|
||||||
_status.mousedragging = null
|
|
||||||
if (skillinfo.preservecancel) ui.create.confirm('c')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import("./interface.js").NonameHookType["uncheckBegin"])[]}
|
|
||||||
*/
|
|
||||||
export const uncheckBegin = []
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import("./interface.js").NonameHookType["uncheckCard"])[]}
|
|
||||||
*/
|
|
||||||
export const uncheckCard = [
|
|
||||||
function removeTempname(card, event) {
|
|
||||||
// @ts-ignore
|
|
||||||
if (!card._tempName) return
|
|
||||||
// @ts-ignore
|
|
||||||
card._tempName.delete()
|
|
||||||
// @ts-ignore
|
|
||||||
delete card._tempName
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import("./interface.js").NonameHookType["uncheckTarget"])[]}
|
|
||||||
*/
|
|
||||||
export const uncheckTarget = [
|
|
||||||
function removeInstance(target, event) {
|
|
||||||
// @ts-ignore
|
|
||||||
if (!target.instance) return
|
|
||||||
// @ts-ignore
|
|
||||||
target.instance.classList.remove('selected')
|
|
||||||
// @ts-ignore
|
|
||||||
target.instance.classList.remove('selectable')
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import("./interface.js").NonameHookType["uncheckButton"])[]}
|
|
||||||
*/
|
|
||||||
export const uncheckButton = []
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {(import("./interface.js").NonameHookType["uncheckEnd"])[]}
|
|
||||||
*/
|
|
||||||
export const uncheckEnd = []
|
|
||||||
|
|
|
@ -3,49 +3,35 @@ import * as buildin from "./buildin.js"
|
||||||
/**
|
/**
|
||||||
* @template {import("./interface.js").NonameHookType} HookType
|
* @template {import("./interface.js").NonameHookType} HookType
|
||||||
* @template {keyof HookType} Name
|
* @template {keyof HookType} Name
|
||||||
|
* @extends {Array<HookType[Name]>}
|
||||||
*/
|
*/
|
||||||
export class NonameHook {
|
export class NonameHook extends Array {
|
||||||
/**
|
/**
|
||||||
* @type {Name}
|
* @type {Name}
|
||||||
*/
|
*/
|
||||||
#name
|
#name
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {HookType[Name][]}
|
|
||||||
*/
|
|
||||||
#methodList
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {Name} name
|
* @param {Name} name
|
||||||
*/
|
*/
|
||||||
constructor(name) {
|
constructor(name) {
|
||||||
|
super()
|
||||||
this.#name = name
|
this.#name = name
|
||||||
this.#methodList = (name in buildin) ? [...buildin[name]] : []
|
|
||||||
|
if (name in buildin) {
|
||||||
|
// @ts-ignore
|
||||||
|
for (const item of buildin[name]) {
|
||||||
|
this.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get [Symbol.species]() {
|
||||||
|
return Array
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return this.#name
|
return this.#name
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {HookType[Name]} method
|
|
||||||
*/
|
|
||||||
add(method) {
|
|
||||||
return this.#methodList.add(method)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {HookType[Name]} method
|
|
||||||
*/
|
|
||||||
push(method) {
|
|
||||||
return this.#methodList.push(method)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
*[Symbol.iterator]() {
|
|
||||||
yield* this.#methodList
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
import { NonameHook } from "./hook.js"
|
import { NonameHook } from "./hook.js"
|
||||||
|
import { defaultAssemblys } from "../assembly/index.js"
|
||||||
|
|
||||||
export const defaultHooks = {
|
export const defaultHooks = {
|
||||||
addGroup: new NonameHook("addGroup"),
|
addGroup: new NonameHook("addGroup"),
|
||||||
addNature: new NonameHook("addNature"),
|
addNature: new NonameHook("addNature"),
|
||||||
|
|
||||||
checkBegin: new NonameHook("checkBegin"),
|
...defaultAssemblys
|
||||||
checkCard: new NonameHook("checkCard"),
|
}
|
||||||
checkTarget: new NonameHook("checkTarget"),
|
|
||||||
checkButton: new NonameHook("checkButton"),
|
export {
|
||||||
checkEnd: new NonameHook("checkEnd"),
|
NonameHook
|
||||||
|
|
||||||
uncheckBegin: new NonameHook("uncheckBegin"),
|
|
||||||
uncheckCard: new NonameHook("uncheckCard"),
|
|
||||||
uncheckTarget: new NonameHook("uncheckTarget"),
|
|
||||||
uncheckButton: new NonameHook("uncheckButton"),
|
|
||||||
uncheckEnd: new NonameHook("uncheckEnd")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,92 +1,94 @@
|
||||||
import { Button, Card, GameEvent, GameEventPromise, Player } from "../element"
|
import { Button, Card, GameEvent, GameEventPromise, Player } from "../element"
|
||||||
|
|
||||||
export interface NonameHookType {
|
export interface NonameHookType {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param id - 势力的id
|
* @param id - 势力的id
|
||||||
* @param short - 势力的短名称(单字称呼)
|
* @param short - 势力的短名称(单字称呼)
|
||||||
* @param name - 势力的完整名称
|
* @param name - 势力的完整名称
|
||||||
* @param config - 关于势力的配置情况
|
* @param config - 关于势力的配置情况
|
||||||
*/
|
*/
|
||||||
addGroup(id: string, short: string, name: string, config: Record<string, unknown>)
|
addGroup(id: string, short: string, name: string, config: Record<string, unknown>): any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param nature - 属性的id
|
* @param nature - 属性的id
|
||||||
* @param translation - 属性的名称
|
* @param translation - 属性的名称
|
||||||
* @param config - 关于属性的配置
|
* @param config - 关于属性的配置
|
||||||
*/
|
*/
|
||||||
addNature(nature: string, translation: string, config: Record<string, unknown>)
|
addNature(nature: string, translation: string, config: Record<string, unknown>): any
|
||||||
|
|
||||||
|
|
||||||
/**
|
// #region Assembly-Compatition
|
||||||
*
|
/**
|
||||||
* @param event - 当前检查的事件
|
*
|
||||||
*/
|
* @param event - 当前检查的事件
|
||||||
checkBegin(event: GameEvent & GameEventPromise)
|
*/
|
||||||
|
checkBegin(event: GameEvent & GameEventPromise): any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param event - 当前检查的事件
|
* @param event - 当前检查的事件
|
||||||
* @param config - 一些配置
|
* @param config - 一些配置
|
||||||
*/
|
*/
|
||||||
checkEnd(event: GameEvent & GameEventPromise, config: { ok: boolean, auto: boolean, autoConfirm: boolean })
|
checkEnd(event: GameEvent & GameEventPromise, config: { ok: boolean, auto: boolean, autoConfirm: boolean }): any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param button - 检查的Button
|
* @param button - 检查的Button
|
||||||
* @param event - 当前检查的事件
|
* @param event - 当前检查的事件
|
||||||
*/
|
*/
|
||||||
checkButton(button: Button, event: GameEvent & GameEventPromise)
|
checkButton(button: Button, event: GameEvent & GameEventPromise): any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param card - 检查的卡牌
|
* @param card - 检查的卡牌
|
||||||
* @param event - 当前检查的事件
|
* @param event - 当前检查的事件
|
||||||
*/
|
*/
|
||||||
checkCard(card: Card, event: GameEvent & GameEventPromise)
|
checkCard(card: Card, event: GameEvent & GameEventPromise): any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param target - 检查的玩家
|
* @param target - 检查的玩家
|
||||||
* @param event - 当前检查的事件
|
* @param event - 当前检查的事件
|
||||||
*/
|
*/
|
||||||
checkTarget(target: Player, event: GameEvent & GameEventPromise)
|
checkTarget(target: Player, event: GameEvent & GameEventPromise): any
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param event - 当前检查的事件
|
* @param event - 当前检查的事件
|
||||||
* @param args - 要取消检查的对象
|
* @param args - 要取消检查的对象
|
||||||
*/
|
*/
|
||||||
uncheckBegin(event: GameEvent & GameEventPromise, args: ("button" | "card" | "target")[] = ["button", "card", "target"])
|
uncheckBegin(event: GameEvent & GameEventPromise, args: ("button" | "card" | "target")[] = ["button", "card", "target"]): any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param event - 当前检查的事件
|
* @param event - 当前检查的事件
|
||||||
* @param args - 要取消检查的对象
|
* @param args - 要取消检查的对象
|
||||||
*/
|
*/
|
||||||
uncheckEnd(event: GameEvent & GameEventPromise, args: ("button" | "card" | "target")[] = ["button", "card", "target"])
|
uncheckEnd(event: GameEvent & GameEventPromise, args: ("button" | "card" | "target")[] = ["button", "card", "target"]): any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param button - 取消检查的Button
|
* @param button - 取消检查的Button
|
||||||
* @param event - 当前检查的事件
|
* @param event - 当前检查的事件
|
||||||
*/
|
*/
|
||||||
uncheckButton(button: Button, event: GameEvent & GameEventPromise)
|
uncheckButton(button: Button, event: GameEvent & GameEventPromise): any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param card - 取消检查的卡牌
|
* @param card - 取消检查的卡牌
|
||||||
* @param event - 当前检查的事件
|
* @param event - 当前检查的事件
|
||||||
*/
|
*/
|
||||||
uncheckCard(card: Card, event: GameEvent & GameEventPromise)
|
uncheckCard(card: Card, event: GameEvent & GameEventPromise): any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param target - 取消检查的玩家
|
* @param target - 取消检查的玩家
|
||||||
* @param event - 当前检查的事件
|
* @param event - 当前检查的事件
|
||||||
*/
|
*/
|
||||||
uncheckTarget(target: Player, event: GameEvent & GameEventPromise)
|
uncheckTarget(target: Player, event: GameEvent & GameEventPromise): any
|
||||||
|
// #endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { Experimental } from "./experimental/index.js";
|
||||||
import * as Element from "./element/index.js";
|
import * as Element from "./element/index.js";
|
||||||
import { updateURLs } from "./update-urls.js";
|
import { updateURLs } from "./update-urls.js";
|
||||||
import { defaultHooks } from "./hooks/index.js"
|
import { defaultHooks } from "./hooks/index.js"
|
||||||
|
import { freezeButExtensible } from "../util/index.js"
|
||||||
|
|
||||||
|
|
||||||
export class Library extends Uninstantable {
|
export class Library extends Uninstantable {
|
||||||
|
@ -153,7 +154,7 @@ export class Library extends Uninstantable {
|
||||||
* 这样当某个地方调用game.callHook(钩子名,[...函数参数])时,就会按顺序将对应数组中的每个函数运行一遍(传参为callHook的第二个参数)。
|
* 这样当某个地方调用game.callHook(钩子名,[...函数参数])时,就会按顺序将对应数组中的每个函数运行一遍(传参为callHook的第二个参数)。
|
||||||
* 你可以将hook机制类比为event.trigger(),但是这里只能放同步代码
|
* 你可以将hook机制类比为event.trigger(),但是这里只能放同步代码
|
||||||
*/
|
*/
|
||||||
static hooks = { ...defaultHooks };
|
static hooks = freezeButExtensible({ ...defaultHooks });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **无名杀频道推送机制**
|
* **无名杀频道推送机制**
|
||||||
|
|
|
@ -25,3 +25,23 @@ export class Uninstantable {
|
||||||
export function delay(ms) {
|
export function delay(ms) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将当前Record已有的普通项封装起来,但不阻止其继续扩展
|
||||||
|
*
|
||||||
|
* @template {object} T
|
||||||
|
* @param {T} record - 要封装的Record
|
||||||
|
* @returns {Readonly<T>}
|
||||||
|
*/
|
||||||
|
export function freezeButExtensible(record) {
|
||||||
|
const descriptors = Object.getOwnPropertyDescriptors(record)
|
||||||
|
if (descriptors) {
|
||||||
|
for (const [key, descriptor] of Object.entries(descriptors)) {
|
||||||
|
if ("value" in descriptor) descriptor.writable = false
|
||||||
|
descriptor.configurable = false
|
||||||
|
Reflect.defineProperty(record, key, descriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return record
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue