增加type文件,音乐盒锁定60帧率

This commit is contained in:
草莓 2025-01-13 18:59:53 +08:00
parent 538a9d9176
commit 6fd1b797a6
19 changed files with 9768 additions and 6 deletions

View File

@ -2600,11 +2600,11 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
(obj.clientWidth - obj.totalWidth) / 2 + "px";
core.dom.musicBtn.style.bottom =
(obj.clientHeight - obj.totalHeight) / 2 - 27 + "px";
let startBackground = core.domStyle.isVertical ?
core.getLocalStorage('end') ? 'project/images/winbackgroundVertical.webp' : main.styles.startVerticalBackground || main.styles.startBackground :
core.getLocalStorage('end') ? 'project/images/winbackground.webp' : main.styles.startBackground;
if (main.dom.startBackground.getAttribute("__src__") != startBackground) {
main.dom.startBackground.setAttribute("__src__", startBackground);
if (!core.isPlaying()) {
const end = core.getLocalStorage('end')
let startBackground = core.domStyle.isVertical ?
end ? 'project/images/winbackgroundVertical.webp' : main.styles.startVerticalBackground || main.styles.startBackground :
end ? 'project/images/winbackground.webp' : main.styles.startBackground;
main.dom.startBackground.src = startBackground;
}
const span = document
@ -15182,7 +15182,13 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
main.core.ui.music.random = main.core.ui.music.randomList.indexOf(main.core.ui.music.musicMx[main.core.ui.music.selection[0]][main.core.ui.music.selection[1]])
page = 0;
music.style.display = "block";
core.registerAnimationFrame("music", null, () => { main.core.ui.music.update() })
let time = 0
core.registerAnimationFrame("music", null, (temptime) => {
if (temptime > time + 1000 / 60) {
time = temptime
main.core.ui.music.update()
}
})
};
},
"横屏切换": function () {

137
project/types/action.d.ts vendored Normal file
View File

@ -0,0 +1,137 @@
/**
*
*/
type MotaMouseFunc = (x: number, y: number, px: number, py: number) => boolean;
/**
*
*/
type MotaKeyboardFunc = (e: KeyboardEvent) => boolean;
/**
*
*/
interface RegisteredActionMap {
keyDown: (keyCode: number) => boolean;
keyDownCtrl: () => boolean;
keyUp: (keyCode: number, altKey: boolean, fromReplay: boolean) => boolean;
longClick: MotaMouseFunc;
onStatusBarClick: (px: number, py: number, vertical: boolean) => boolean;
ondown: MotaMouseFunc;
onkeyDown: MotaKeyboardFunc;
onkeyUp: MotaKeyboardFunc;
onmousewheel: (direct: 1 | -1) => boolean;
onmove: MotaMouseFunc;
onup: MotaMouseFunc;
pressKey: (keyCode: number) => boolean;
}
type ActionKey = keyof RegisteredActionMap;
/**
* void就变成了actions上的函数...
*/
type VoidedActionFuncs = {
[P in ActionKey]: (...params: Parameters<RegisteredActionMap[P]>) => void;
};
/**
*
*/
interface ClickLoc extends Loc {
/**
* 32
*/
size: 32;
}
interface RegisteredActionOf<K extends ActionKey> {
/**
*
*/
action: K;
/**
*
*/
name: string;
/**
*
*/
priority: number;
/**
*
*/
func: RegisteredActionMap[K];
}
/**
*
*/
interface Actions extends VoidedActionFuncs {
/**
*
*/
readonly LAST: number;
/**
*
*/
readonly _HX_: number;
/**
*
*/
readonly _HY_: number;
/**
*
*/
readonly actionsdata: ActionData;
/**
*
*/
readonly actions: {
[P in ActionKey]: RegisteredActionOf<P>[];
};
/**
*
* @param action
* @param name 使
* @param func func返回true
* @param priority 0
*/
registerAction<K extends ActionKey>(
action: K,
name: string,
func: RegisteredActionMap[K],
priority?: number
): void;
/**
*
* @param action
* @param name
*/
unregisterAction(action: ActionKey, name: string): void;
/**
*
*/
doRegisteredAction<K extends ActionKey>(
action: K,
...params: Parameters<RegisteredActionMap[K]>
): void;
/**
* (_HX_ - 2, _HX_ + 2)
* @param x
*/
_out(x: number): boolean;
}
declare const actions: new () => Actions;

1104
project/types/control.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

1450
project/types/core.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

140
project/types/data.d.ts vendored Normal file
View File

@ -0,0 +1,140 @@
interface MainData {
/**
* id
*/
readonly floorIds: FloorIds[];
/**
*
*/
readonly floorPatitions: [FloorIds, FloorIds?][];
/**
*
*/
readonly tilesets: string[];
/**
*
*/
readonly animates: AnimationIds[];
/**
* bgm
*/
readonly bgms: BgmIds[];
/**
*
*/
readonly sounds: SoundIds[];
/**
*
*/
readonly fonts: FontIds[];
/**
*
*/
readonly nameMap: NameMap;
/**
*
*/
readonly levelChoose: LevelChooseEvent[];
/**
*
*/
readonly equipName: string[];
/**
* bgm
*/
readonly startBgm: BgmIds;
/**
*
*/
readonly styles: MainStyle;
/**
*
*/
readonly splitImages: SplitImageData;
}
interface FirstData {
/**
*
*/
title: string;
/**
* mota.config.ts中的一致
*/
name: string;
/**
*
*/
version: string;
/**
*
*/
floorId: FloorIds;
/**
*
*/
hero: HeroStatus;
/**
*
*/
startCanvas: MotaEvent;
/**
*
*/
startText: MotaEvent;
/**
*
*/
shops: ShopEventOf<keyof ShopEventMap>[];
/**
*
*/
levelUp: LevelUpEvent;
}
/**
*
*/
interface DataCore {
/**
* main信息
*/
readonly main: MainData;
/**
*
*/
readonly firstData: FirstData;
/**
*
*/
readonly values: CoreValues;
/**
*
*/
readonly flags: CoreFlags;
}
declare const data: new () => Omit<DataCore, 'main'>;

382
project/types/enemy.d.ts vendored Normal file
View File

@ -0,0 +1,382 @@
type PartialNumbericEnemyProperty =
| 'value'
| 'zone'
| 'repulse'
| 'laser'
| 'breakArmor'
| 'counterAttack'
| 'vampire'
| 'hpBuff'
| 'atkBuff'
| 'defBuff'
| 'range'
| 'haloRange'
| 'n'
| 'purify'
| 'atkValue'
| 'defValue'
| 'damage';
type BooleanEnemyProperty =
| 'zoneSquare'
| 'haloSquare'
| 'notBomb'
| 'add'
| 'haloAdd';
type Enemy<I extends EnemyIds = EnemyIds> = {
/**
* id
*/
id: I;
/**
*
*/
name: string;
/**
* IDnullID来替换该怪物原本的ID
*
*/
displayIdInBook: EnemyIds;
/**
*
*/
beforeBattle: MotaEvent;
/**
*
*/
afterBattle: MotaEvent;
} & {
[P in PartialNumbericEnemyProperty]?: number;
} & {
[P in BooleanEnemyProperty]: boolean;
} & EnemyInfoBase;
/**
*
*/
type EnemySpecialDeclaration = [
id: number,
name: string | ((enemy: Enemy) => string),
desc: string | ((enemy: Enemy) => string),
color: Color,
extra?: number
];
interface DamageString {
/**
*
*/
damage: string;
/**
*
*/
color: Color;
}
interface EnemyInfoBase {
/**
*
*/
hp: number;
/**
*
*/
atk: number;
/**
*
*/
def: number;
/**
*
*/
money: number;
/**
*
*/
exp: number;
/**
*
*/
point: number;
/**
*
*/
special: number[];
}
interface EnemyInfo extends EnemyInfoBase {
/**
*
*/
guards: [x: number, y: number, id: EnemyIds];
}
interface DamageInfo {
/**
*
*/
mon_hp: number;
/**
*
*/
mon_atk: number;
/**
*
*/
mon_def: number;
/**
*
*/
init_damage: number;
/**
*
*/
per_damage: number;
/**
*
*/
hero_per_damage: number;
/**
*
*/
turn: number;
/**
*
*/
damage: number;
}
interface BookEnemyInfo extends Enemy, EnemyInfo {
/**
*
*/
locs?: [x: number, y: number][];
/**
*
*/
name: string;
/**
*
*/
specialText: string[];
/**
*
*/
specialColor: Color[];
/**
*
*/
damage: number;
/**
*
*/
critical: number;
/**
*
*/
criticalDamage: number;
/**
* ratio防减伤
*/
defDamage: number;
}
/**
*
*/
interface Enemys extends EnemyData {
/**
*
*/
readonly enemys: {
[P in EnemyIds]: Enemy<P>;
};
/**
*
*/
readonly enemydata: EnemyData;
/**
*
*/
getEnemys(): {
[P in EnemyIds]: Enemy<P>;
};
/**
*
* @example core.getSpecialText('greenSlime') // ['先攻', '3连击', '破甲', '反击']
* @param enemy id或敌人对象core.material.enemys.greenSlime
* @returns
*/
getSpecialText(enemy: EnemyIds | Enemy): string[];
/**
*
* @param enemy id或敌人对象core.material.enemys.greenSlime
*/
getSpecialColor(enemy: EnemyIds | Enemy): Color[];
/**
*
* @param enemy id或敌人对象core.material.enemys.greenSlime
*/
getSpecialFlag(enemy: EnemyIds | Enemy): number[];
/**
*
* @example core.getSpecialHint('bat', 1) // '先攻:怪物首先攻击'
* @param enemy id或敌人对象
* @param special
* @returns
*/
getSpecialHint(enemy: EnemyIds | Enemy, special: number): string;
/**
*
* @param enemy id或敌人对象
* @param name
* @param x
* @param y
* @param floorId
*/
getEnemyValue<K extends keyof Enemy>(
enemy: EnemyIds | Enemy,
name: K,
x?: number,
y?: number,
floorId?: FloorIds
): Enemy[K];
/**
*
* @example core.canBattle('greenSlime',0,0,'MT0') // 能否打败主塔0层左上角的绿头怪假设有
* @param enemy id或敌人对象
* @param x
* @param y
* @param floorId
* @returns true表示可以打败false表示无法打败
*/
canBattle(
enemy: EnemyIds | Enemy,
x?: number,
y?: number,
floorId?: FloorIds
): boolean;
/**
*
* @example core.getDamageString('greenSlime', 0, 0, 'MT0') // 绿头怪的地图显伤
* @param enemy id或敌人对象
* @param x
* @param y
* @param floorId
*/
getDamageString(
enemy: EnemyIds | Enemy,
x?: number,
y?: number,
floorId?: FloorIds
): DamageString;
/**
* useLoop开关选择回合法或二分法
* @example core.nextCriticals('greenSlime', 9, 0, 0, 'MT0') // 绿头怪接下来的9个临界
* @param enemy id或敌人对象
* @param number 1
* @param x
* @param y
* @param floorId
* @returns
*/
nextCriticals(
enemy: EnemyIds | Enemy,
number?: number,
x?: number,
y?: number,
floorId?: FloorIds
): [critical: number, damage: number][];
/**
* 使
* @example core.nextCriticals('greenSlime', 10, 0, 0, 'MT0') // 再加10点防御能使绿头怪的伤害降低多少
* @param enemy id或敌人对象
* @param k 1
* @param x
* @param y
* @param floorId
* @returns
*/
getDefDamage(
enemy: EnemyIds | Enemy,
k?: number,
x?: number,
y?: number,
floorId?: FloorIds
): number;
/**
*
* @example core.getDamage('greenSlime',0,0,'MT0') // 绿头怪的总伤害
* @param enemy id或敌人对象
* @param x
* @param y
* @param floorId
* @returns null
*/
getDamage(
enemy: EnemyIds | Enemy,
x?: number,
y?: number,
floorId?: FloorIds
): number;
/**
*
* @example core.getCurrentEnemys('MT0') // 主塔0层的敌人集合
* @param floorId id
* @returns
*/
getCurrentEnemys(floorId?: FloorIds): Enemy[];
/**
*
* @example core.hasEnemyLeft('greenSlime', ['sample0', 'sample1']) // 样板0层和1层是否有漏打的绿头怪
* @param enemyId id
* @param floorId id或其数组
* @returns true表示有敌人被漏打false表示敌人已死光
*/
hasEnemyLeft(
enemyId?: EnemyIds | EnemyIds[],
floorId?: FloorIds | FloorIds[]
): boolean;
}
declare const enemys: new () => Enemys;

763
project/types/event.d.ts vendored Normal file
View File

@ -0,0 +1,763 @@
/**
*
*/
type SystemEventFunc = (data: any, callback: (...params: any[]) => any) => void;
/**
*
*/
type EventFunc = (data: any, x?: number, y?: number, prefix?: string) => void;
/**
*
*/
interface Events extends EventData {
/**
*
*/
eventdata: EventData;
/**
*
*/
commonEvent: Record<EventDeclaration, MotaEvent>;
/**
*
*/
systemEvent: Record<string, SystemEventFunc>;
/**
*
*/
actions: Record<string, EventFunc>;
/**
*
* @example core.startGame('咸鱼乱撞', 0, ''); // 开始一局咸鱼乱撞难度的新游戏随机种子为0
* @param hard
* @param seed
* @param route base64压缩后的录像
* @param callback
*/
startGame(
hard: string,
seed: number,
route?: string,
callback?: () => void
): void;
/**
*
* @example core.gameOver(); // 游戏失败
* @param ending
* @param fromReplay true表示在播放录像
* @param norank true表示不计入榜单
*/
gameOver(ending?: string, fromReplay?: boolean, norank?: boolean): void;
/**
*
*/
restart(): void;
/**
*
*/
confirmRestart(): void;
/**
*
* @param type
* @param func (data,callback)
*/
registerSystemEvent(type: string, func: SystemEventFunc): void;
/**
*
* @param type
*/
unregisterSystemEvent(type: string): void;
/**
*
* @param type
* @param data
* @param callback
*/
doSystemEvent(
type: string,
data: any,
callback?: (...params: any[]) => any
): void;
/**
* (x,y)script属性
* @param x
* @param y
* @param callback
*/
trigger(x: number, y: number, callback?: () => void): void;
/**
*
* @example core.battle('greenSlime'); // 和从天而降的绿头怪战斗(如果打得过)
* @param id id
* @param x
* @param y
* @param force true表示强制战斗
* @param callback
*/
battle(
id: AllIdsOf<'enemys' | 'enemy48'>,
x?: number,
y?: number,
force?: boolean,
callback?: () => void
): void;
/**
*
* @example core.openDoor(0, 0, true, core.jumpHero); // 打开左上角的门,需要钥匙,然后主角原地跳跃半秒
* @param x
* @param y
* @param needKey true表示需要钥匙
* @param callback
*/
openDoor(
x: number,
y: number,
needKey?: boolean,
callback?: () => void
): void;
/**
*
* @example core.getItem('book'); // 获得敌人手册并提示
* @param id id
* @param num 1
* @param x
* @param y
* @param callback
*/
getItem(
id: AllIdsOf<'items'>,
num?: number,
x?: number,
y?: number,
callback?: () => void
): void;
/**
*
* @param noRoute true则不计入录像
*/
getNextItem(noRoute?: boolean): void;
/**
*
* @example core.changeFloor('MT0'); // 传送到主塔0层主角坐标和朝向不变黑屏时间取用户设置值
* @param floorId id':before'':after'
* @param stair ':now',':symmetry',':symmetry_x',':symmetry_y'id'downFloor''upFloor'
* @param heroLoc
* @param time
* @param callback
*/
changeFloor(
floorId: FloorIds,
stair?: FloorChangeStair | AllIds,
heroLoc?: Partial<Loc>,
time?: number,
callback?: () => void
): void;
/**
*
* @param floorId id
*/
hasVisitedFloor(floorId?: FloorIds): boolean;
/**
*
* @param floorId id
*/
visitFloor(floorId?: FloorIds): void;
/**
*
* @param data
*/
pushBox(data?: Block): void;
/**
*
*/
onSki(number?: number): boolean;
/**
*
* @param type
* @param func (data, x, y, prefix)
* data为事件内容x和y为当前点坐标nullprefix为当前点前缀
*/
registerEvent(type: string, func: EventFunc): void;
/**
*
* @param type
*/
unregisterEvent(type: string): void;
/**
*
* @param data
* @param x
* @param y
* @param prefix
*/
doEvent(data: any, x?: number, y?: number, prefix?: string): void;
/**
*
* @param list
* @param x
* @param y
* @param callback
*/
setEvents(
list: MotaEvent,
x?: number,
y?: number,
callback?: () => void
): void;
/**
*
* @param list
* @param x
* @param y
* @param callback
*/
startEvents(
list?: MotaEvent,
x?: number,
y?: number,
callback?: () => void
): void;
/**
*
* @example
* // 事件中的原生脚本,配合勾选“不自动执行下一个事件”来达到此改变色调只持续到下次场景切换的效果
* core.setCurtain([0,0,0,1], undefined, null, core.doAction);
*/
doAction(): void;
/**
* core.insertCommonEvent
* @example core.insertAction('一段文字'); // 插入一个显示文章
* @param action
* @param x
* @param y
* @param callback
* @param addToLast true表示插入到末尾
*/
insertAction(
action: MotaEvent | MotaAction,
x?: number,
y?: number,
callback?: () => void,
addToLast?: boolean
): void;
/**
*
* @example core.insertCommonEvent('加点事件', [3]);
* @param name
* @param args flag:arg1, flag:arg2, ...
* @param x
* @param y
* @param callback
* @param addToLast true表示插入到末尾
*/
insertCommonEvent(
name: EventDeclaration,
args?: any[],
x?: number,
y?: number,
callback?: () => void,
addToLast?: boolean
): void;
/**
*
* @param name
*/
getCommonEvent(name: EventDeclaration): any;
/**
*
* @param data
*/
recoverEvents(data?: any): void;
/**
*
*/
checkAutoEvents(): void;
/**
*
* @param symbol
* @param value
*/
autoEventExecuting(symbol?: string, value?: any): boolean;
/**
*
* @param symbol
* @param value
*/
autoEventExecuted(symbol?: string, value?: any): boolean;
/**
*
*/
pushEventLoc(x: number, y: number, floorId?: FloorIds): void;
/**
*
*/
popEventLoc(): void;
/**
*
* @param data
*/
precompile(data?: any): any;
/**
*
* @param fromUserAction
*/
openBook(fromUserAction?: boolean): void;
/**
*
* @param fromUserAction
*/
useFly(fromUserAction?: boolean): void;
/** 点击装备栏时的打开操作 */
openEquipbox(fromUserAction?: boolean): void;
/**
*
* @param fromUserAction
*/
openToolbox(fromUserAction?: boolean): void;
/**
*
* @param fromUserAction
*/
openQuickShop(fromUserAction?: boolean): void;
/**
*
* @param fromUserAction
*/
openKeyBoard(fromUserAction?: boolean): void;
/**
*
* @param fromUserAction
*/
save(fromUserAction?: boolean): void;
/**
*
* @param fromUserAction
*/
load(fromUserAction?: boolean): void;
/**
*
* @param fromUserAction
*/
openSettings(fromUserAction?: boolean): void;
/**
*
*/
hasAsync(): boolean;
/**
*
*/
stopAsync(): void;
/**
*
*/
hasAsyncAnimate(): boolean;
/**
*
* @param name 4x4的行走图名称
*/
follow(name: ImageIds | NameMapIn<ImageIds>): void;
/**
*
* @param name
*/
unfollow(name?: ImageIds | NameMapIn<ImageIds>): void;
/**
*
* @param name
* @param operator
* @param value
* @param prefix
*/
setValue(
name: `${EventValuePreffix}:${string}`,
operator: MotaOperator,
value: number,
prefix?: string
): void;
/**
*
* @example core.setEnemy('greenSlime', 'def', 0); // 把绿头怪的防御设为0
* @param id id
* @param name
* @param value
* @param operator
* @param prefix
* @param norefresh
*/
setEnemy<K extends keyof Enemy>(
id: AllIdsOf<'enemys' | 'enemy48'>,
name: K,
value: Enemy[K],
operator?: MotaOperator,
prefix?: string,
norefresh?: boolean
): void;
/**
*
* @param x
* @param y
* @param floorId id
* @param name
* @param value
* @param operator
* @param prefix
* @param norefresh
*/
setEnemyOnPoint<K extends keyof Enemy>(
x: number,
y: number,
floorId: FloorIds,
name: K,
value: Enemy[K],
operator?: MotaOperator,
prefix?: string,
norefresh?: boolean
): void;
/**
*
* @param x
* @param y
* @param floorId id
* @param norefresh
*/
resetEnemyOnPoint(
x: number,
y: number,
floorId?: FloorIds,
norefresh?: boolean
): void;
/**
*
* @param fromX
* @param fromY
* @param toX
* @param toY
* @param floorId id
* @param norefresh
*/
moveEnemyOnPoint(
fromX: number,
fromY: number,
toX: number,
toY: number,
floorId?: FloorIds,
norefresh?: boolean
): void;
/**
*
* @example core.setFloorInfo('ratio', 2, 'MT0'); // 把主塔0层的血瓶和宝石变为双倍效果
* @param name
* @param values
* @param floorId id
* @param prefix
*/
setFloorInfo<K extends keyof Floor>(
name: K,
values?: Floor[K],
floorId?: FloorIds,
prefix?: string
): void;
/**
*
* @param name
* @param value
*/
setGlobalAttribute<K extends keyof GlobalAttribute>(
name: K,
value: GlobalAttribute[K]
): void;
/**
*
* @example core.setGlobalFlag('steelDoorWithoutKey', true); // 使全塔的所有铁门都不再需要钥匙就能打开
* @param name
* @param value !core.flags[name]
*/
setGlobalFlag<K extends keyof CoreFlags>(
name: K,
value: CoreFlags[K]
): void;
/**
*
* @param name
* @param value
*/
setNameMap(name: string, value?: SourceIds): void;
/**
*
*/
setTextAttribute(data: Partial<TextAttribute>): void;
/**
*
* @param code
* @param loc
* @param relative
* @param moveMode
* @param time
* @param callback
*/
moveTextBox(
code: number,
loc: LocArr,
relative?: boolean,
moveMode?: EaseMode,
time?: number,
callback?: () => void
): void;
/**
*
* @param code
* @param callback
*/
clearTextBox(code: number, callback: () => void): void;
/**
*
* @example core.closeDoor(0, 0, 'yellowWall', core.jumpHero); // 在左上角关掉一堵黄墙,然后主角原地跳跃半秒
* @param x
* @param y
* @param id id
* @param callback
*/
closeDoor(
x: number,
y: number,
id: AllIdsOf<Exclude<Cls, 'enemys' | 'enemy48'>>,
callback?: () => void
): void;
/**
*
* @example
* // 裁剪winskin.png的最左边128×128px放大到铺满整个视野1秒内淡入到50%透明编号为1
* core.showImage(1, core.material.images.images['winskin.png'], [0,0,128,128], [0,0,416,416], 0.5, 1000);
* @param code 50100z值z值为125UI层为140
* @param image
* @param sloc
* @param loc
* @param opacityVal 11
* @param time 0
* @param callback
*/
showImage(
code: number,
image: ImageIds | NameMapIn<ImageIds> | ImageSource,
sloc?: [number, number, number, number],
loc?: [number, number, number?, number?],
opacityVal?: number,
time?: number,
callback?: () => void
): void;
/**
*
* @example core.hideImage(1, 1000, core.jumpHero); // 1秒内淡出1号图片然后主角原地跳跃半秒
* @param code
* @param time
* @param callback
*/
hideImage(code: number, time?: number, callback?: () => void): void;
/**
* /
* @example core.moveImage(1, null, 0.5); // 1秒内把1号图片变为50%透明
* @param code
* @param to
* @param opacityVal
* @param moveMode
* @param time 1
* @param callback
*/
moveImage(
code: number,
to?: LocArr,
opacityVal?: number,
moveMode?: string,
time?: number,
callback?: () => void
): void;
/**
*
* @param code
* @param center
* @param angle
* @param moveMode
* @param time 1
* @param callback
*/
rotateImage(
code: number,
center?: LocArr,
angle?: number,
moveMode?: EaseMode,
time?: number,
callback?: () => void
): void;
/**
*
* @param code
* @param center
* @param scale
* @param moveMode
* @param time 1
* @param callback
*/
scaleImage(
code: number,
center?: LocArr,
scale?: number,
moveMode?: string,
time?: number,
callback?: () => void
): void;
/**
*
* @example core.showGif(); // 擦除所有动图
* @param name
* @param x
* @param y
*/
showGif(
name?:
| Extract<ImageIds, EndsWith<'.gif'>>
| NameMapIn<Extract<ImageIds, EndsWith<'.gif'>>>,
x?: number,
y?: number
): void;
/**
* bgm的音量
* @example core.setVolume(0, 100, core.jumpHero); // 0.1秒内淡出bgm然后主角原地跳跃半秒
* @param value 01
* @param time 1000
* @param callback
*/
setVolume(value: number, time?: number, callback?: () => void): void;
/**
*
* @example core.vibrate(); // 视野左右抖动1秒
* @param direction
* @param time
* @param speed
* @param power
* @param callback
*/
vibrate(
direction?: string,
time?: number,
speed?: number,
power?: number,
callback?: () => void
): void;
/**
* 退
* @example core.eventMoveHero(['forward'], 125, core.jumpHero); // 主角强制前进一步用时1/8秒然后主角原地跳跃半秒
* @param steps 退
* @param time 00.1
* @param callback
*/
eventMoveHero(steps: Step[], time?: number, callback?: () => void): void;
/**
* ex和ey为目标点的坐标null表示原地跳跃time为总跳跃时间
* @example core.jumpHero(); // 主角原地跳跃半秒
* @param ex
* @param ey
* @param time
* @param callback
*/
jumpHero(
ex?: number,
ey?: number,
time?: number,
callback?: () => void
): void;
/**
*
* @example core.setHeroIcon('npc48.png', true); // 把主角从阳光变成样板0层左下角的小姐姐但不立即刷新
* @param name core.status.hero.image
* @param noDraw true表示不立即刷新
*/
setHeroIcon(name: string, noDraw?: boolean): void;
/** 检查升级事件 */
checkLvUp(): void;
/**
* 使
* @example core.tryUseItem('pickaxe'); // 尝试使用破墙镐
* @param itemId id
*/
tryUseItem(itemId: ItemIdOf<'tools' | 'constants'>): void;
}
declare const events: new () => Events;

313
project/types/eventDec.d.ts vendored Normal file
View File

@ -0,0 +1,313 @@
type MotaAction = any;
type MotaEvent = any[];
/**
*
*/
type ShopEventOf<T extends keyof ShopEventMap> = ShopEventMap[T];
interface ShopEventMap {
/**
*
*/
common: CommonShopEvent;
/**
*
*/
item: ItemShopEvent;
/**
*
*/
event: CommonEventShopEvent;
}
interface ShopEventBase {
/**
* id
*/
id: string;
/**
*
*/
textInList: string;
/**
*
*/
mustEnable: boolean;
/**
*
*/
disablePreview: boolean;
}
/**
*
*/
interface CommonShopChoice {
/**
*
*/
text: string;
/**
*
*/
need: string;
/**
*
*/
icon: AllIds;
/**
*
*/
color: Color;
/**
*
*/
action: MotaEvent;
}
/**
*
*/
interface CommonShopEvent extends ShopEventBase {
/**
*
*/
text: string;
/**
*
*/
choices: CommonShopChoice[];
}
/**
*
*/
interface ItemShopChoice {
/**
* id
*/
id: AllIdsOf<'items'>;
/**
*
*/
number: number;
/**
* ${}
*/
money: string;
/**
*
*/
sell: string;
/**
*
*/
condition: string;
}
/**
*
*/
interface ItemShopEvent extends ShopEventBase {
/**
*
*/
item: true;
/**
* 西
*/
use: 'money' | 'exp';
/**
*
*/
choices: ItemShopChoice[];
}
interface CommonEventShopEvent {
/**
* 使
*/
commonEvent: EventDeclaration;
}
interface AutoEventBase {
/**
*
*/
condition: string;
/**
*
*/
currentFloor: boolean;
/**
*
*/
priority: number;
/**
*
*/
delayExecute: boolean;
/**
*
*/
multiExecute: boolean;
/**
*
*/
data: MotaEvent;
}
interface AutoEvent extends AutoEventBase {
/**
* id
*/
floorId: FloorIds;
/**
*
*/
index: string;
/**
*
*/
x: number;
/**
*
*/
y: number;
/**
*
*/
symbol: string;
}
interface LevelChooseEvent {
/**
*
*/
title: string;
/**
*
*/
name: string;
/**
* hard值
*/
hard: number;
/**
*
*/
color: RGBArray;
/**
*
*/
action: MotaEvent;
}
interface LevelUpEvent {
/**
*
*/
need: number;
/**
*
*/
title: string;
/**
*
*/
action: MotaEvent;
}
/**
*
*/
interface DoorInfo {
/**
*
*/
time: number;
/**
*
*/
openSound: SoundIds;
/**
*
*/
closeSound: SoundIds;
/**
*
*/
keys: Partial<Record<ItemIdOf<'tools'> | `${ItemIdOf<'tools'>}:o`, number>>;
/**
*
*/
afterOpenDoor?: MotaEvent;
}
interface ChangeFloorEvent {
/**
*
*/
floorId: ':before' | ':after' | ':now' | FloorIds;
/**
* stair就无效了
*/
loc?: LocArr;
/**
*
*/
stair?: FloorChangeStair;
/**
*
*/
direction?: HeroTurnDir;
/**
*
*/
time?: number;
/**
* 穿
*/
ignoreChangeFloor?: boolean;
}

456
project/types/eventStatus.d.ts vendored Normal file
View File

@ -0,0 +1,456 @@
interface EventStatusDataMap {
/**
*
*/
action: ActionStatusData;
/**
*
*/
book: number;
/**
*
*/
fly: number;
/**
*
*/
viewMaps: ViewMapStatusData;
/**
*
*/
equipbox: EquipboxStatusData;
/**
*
*/
toolbox: ToolboxStatusData;
/**
*
*/
save: SaveStatusData;
load: SaveStatusData;
replayLoad: SaveStatusData;
replayRemain: SaveStatusData;
replaySince: SaveStatusData;
/**
*
*/
text: TextStatusData;
/**
*
*/
confirmBox: ConfirmStatusData;
/**
*
* 西
*/
about: null;
help: null;
'book-detail': null;
keyBoard: null;
switchs: null;
'switchs-sounds': null;
'switchs-display': null;
'switchs-action': null;
settings: null;
selectShop: null;
notes: null;
syncSave: null;
syncSelect: null;
localSaveSelect: null;
storageRemove: null;
cursor: null;
replay: null;
gameInfo: null;
}
interface _EventStatusSelectionMap {
/**
*
*/
action: number;
/**
*
*/
equipbox: number;
/**
*
*/
toolbox: number;
/**
*
*/
save: boolean;
load: boolean;
/**
* (0)(1)
*/
confirmBox: 0 | 1;
/**
*
*/
switchs: number;
'switchs-sounds': number;
'switchs-display': number;
'switchs-action': number;
settings: number;
notes: number;
syncSave: number;
syncSelect: number;
localSaveSelect: number;
storageRemove: number;
replay: number;
gameInfo: number;
}
interface _EventStatusUiMap {
/**
*
*/
action: ActionStatusUi;
/**
* id
*/
book: number;
/**
*
*/
confirmBox: string;
/**
*
*/
'switchs-display': SwitchsStatusData;
/**
*
*/
settings: SwitchsStatusData;
/**
*
*/
selectShop: SelectShopStatusUi;
notes: SelectShopStatusUi;
syncSave: SelectShopStatusUi;
syncSelect: SelectShopStatusUi;
localSaveSelect: SelectShopStatusUi;
storageRemove: SelectShopStatusUi;
gameInfo: SelectShopStatusUi;
}
interface _EventStatusIntervalMap {
/**
* (?
*/
action: ActionStatusData;
/**
* 退
*/
book: ActionStatusData;
/**
* 退
*/
save: ActionStatusData;
load: ActionStatusData;
}
interface _EventStatusTimeoutMap {
/**
*
*/
action: number;
}
interface _EventStatusAnimateUiMap {
/**
*
*/
action: number;
}
type EventStatus = keyof EventStatusDataMap;
type _FillEventStatus<T> = {
[P in EventStatus]: P extends keyof T ? T[P] : null;
};
type EventStatusSelectionMap = _FillEventStatus<_EventStatusSelectionMap>;
type EventStatusUiMap = _FillEventStatus<_EventStatusUiMap>;
type EventStatusIntervalMap = _FillEventStatus<_EventStatusIntervalMap>;
type EventStatusTimeoutMap = _FillEventStatus<_EventStatusTimeoutMap>;
type EventStatusAnimateUiMap = _FillEventStatus<_EventStatusAnimateUiMap>;
/**
*
*/
interface EventStatusOf<T extends EventStatus = EventStatus> {
/**
*
*/
id: T;
/**
*
*/
data: EventStatusDataMap[T];
/**
*
*/
selection: EventStatusSelectionMap[T];
/**
* ui信息
*/
ui: EventStatusUiMap[T];
/**
*
*/
interval: EventStatusIntervalMap[T];
/**
*
*/
timeout: EventStatusTimeoutMap[T];
/**
*
*/
animateUi: EventStatusAnimateUiMap[T];
}
interface ActionStatusEventList {
/**
*
*/
todo: MotaEvent;
/**
*
*/
total: MotaEvent;
/**
*
*/
contidion: string;
}
interface ActionLocStackInfo {
/**
*
*/
x: number;
/**
*
*/
y: number;
/**
* id
*/
floorId: FloorIds;
}
/**
*
*/
interface ActionStatusData {
/**
*
*/
list: DeepReadonly<ActionStatusEventList>;
/**
*
*/
x?: number;
/**
*
*/
y?: number;
/**
*
*/
callback?: () => void;
/**
*
*/
appendingEvents: MotaEvent[];
/**
*
*/
locStack: any[];
/**
*
*/
type: EventType;
/**
*
*/
current: MotaAction;
}
interface ActionStatusUi {
/**
*
*/
text: string;
/**
*
*/
yes?: MotaEvent;
/**
*
*/
no?: MotaEvent;
/**
*
*/
choices?: string[];
/**
*
*/
width?: number;
}
interface ViewMapStatusData {
/**
*
*/
index: number;
/**
*
*/
damage: boolean;
/**
*
*/
all: boolean;
/**
*
*/
x: number;
/**
*
*/
y: number;
}
interface EquipboxStatusData {
/**
*
*/
page: number;
/**
*
*/
selectId: ItemIdOf<'equips'>;
}
interface ToolboxStatusData {
/**
*
*/
toolsPage: number;
/**
*
*/
constantsPage: number;
/**
* id
*/
selectId: ItemIdOf<'constants' | 'tools'>;
}
interface SaveStatusData {
/**
*
*/
page: number;
/**
*
*/
offset: number;
/**
* fav表示收藏all表示所有存档
*/
mode: 'fav' | 'all';
}
interface TextStatusData {
/**
*
*/
list: string[];
/**
*
*/
callback: () => void;
}
interface ConfirmStatusData {
/**
*
*/
yes: () => void;
/**
*
*/
no: () => void;
}
interface SwitchsStatusData {
/**
*
*/
choices: string[];
}
interface SelectShopStatusUi {
/**
*
*/
offset: number;
}

282
project/types/function.d.ts vendored Normal file
View File

@ -0,0 +1,282 @@
interface ActionData {
/**
*
* @param keyCode keyCode
* @param altKey alt键
*/
onKeyUp(keyCode: number, altKey: boolean): boolean;
/**
*
* @param px
* @param py
* @param vertical
*/
onClickStatusBar(px: number, py: number, vertical: boolean): boolean;
}
interface ControlData {
/**
*
*/
saveData(): Save;
/**
*
* @param data
* @param callback
*/
loadData(data: Save, callback?: () => void): void;
/**
*
* @param name
*/
getStatusLabel(name: string): string;
/**
* debuff
* @param action get表示获得debuffremove表示移除debuff
* @param type debuff列表
*/
triggerDebuff(action: 'get' | 'remove', type: string | string[]): void;
/**
*
*/
updateStatusBar(): void;
/**
*
* @param floorId id
*/
updateCheckBlock(floorId: FloorIds): void;
/**
*
* @param callback
*/
moveOneStep(callback?: () => void): void;
/**
*
* @param x
* @param y
* @param ignoreSteps
*/
moveDirectly(x: number, y: number, ignoreSteps?: number): boolean;
/**
*
* @param time
*/
parallelDo(time: number): void;
}
interface EnemyData {
/**
*
*/
getSpecials(): EnemySpecialDeclaration[];
/**
*
* @param enemy id或敌人对象
* @param hero core.status.hero获取
* @param x
* @param y
* @param floorId
*/
getEnemyInfo(
enemy: EnemyIds | Enemy,
hero?: HeroStatus,
x?: number,
y?: number,
floorId?: FloorIds
): EnemyInfo;
/**
*
* @param enemy id或敌人对象
* @param hero core.status.hero获取
* @param x
* @param y
* @param floorId
*/
getDamageInfo(
enemy: EnemyIds | Enemy,
hero?: HeroStatus,
x?: number,
y?: number,
floorId?: FloorIds
): DamageInfo;
/**
*
* @example core.hasSpecial('greenSlime', 1) // 判定绿头怪有无先攻属性
* @param special id或敌人对象或正整数数组或自然数
* @param test
* @returns special为数组或数且含有test或相等special为敌人id或对象且具有此属性true
*/
hasSpecial(
special: number | number[] | EnemyIds | Enemy,
test: number
): boolean;
}
interface UiData {
/**
*
* @param cls
*/
getToolboxItems<T extends Exclude<ItemCls, 'items'>>(cls: T): ItemIdOf<T>[];
/**
*
*/
drawStatusBar(): void;
/**
*
*/
drawStatistics(): AllIdsOf<'items'>[];
/**
*
*/
drawAbout(): void;
}
interface EventData {
/**
*
* @param hero
* @param hard
* @param floorId
* @param maps
* @param values
*/
resetGame(
hero: HeroStatus,
hard: string,
floorId: FloorIds,
maps: GameStatus['maps'],
values: Partial<CoreValues>
): void;
/**
*
* @param reason
* @param norank
* @param noexit 退
*/
win(reason: string, norank?: boolean, noexit?: boolean): void;
/**
*
* @param reason
*/
lose(reason: string): void;
/**
*
* @param floorId
* @param heroLoc
*/
changingFloor(floorId: FloorIds, heroLoc: Loc): void;
/**
*
* @param floorId
*/
afterChangeFloor(floorId: FloorIds): void;
/**
*
* @param toId
* @param callback
*/
flyTo(toId: FloorIds, callback: () => void): void;
/**
*
* @param enemyId
* @param x
* @param y
*/
beforeBattle(
enemyId: AllIdsOf<'enemys' | 'enemy48'>,
x?: number,
y?: number
): void;
/**
*
* @param enemyId
* @param x
* @param y
*/
afterBattle(
enemyId: AllIdsOf<'enemys' | 'enemy48'>,
x?: number,
y?: number
): void;
/**
*
* @param doorId id
* @param x
* @param y
*/
afterOpenDoor(
doorId: AllIdsOf<Exclude<Cls, 'enemys' | 'enemy48'>>,
x: number,
y: number
): void;
/**
*
* @param itemId id
* @param x
* @param y
* @param isGentleClick
*/
afterGetItem(
itemId: AllIdsOf<'items'>,
x: number,
y: number,
isGentleClick?: boolean
): void;
/**
*
*/
afterPushBox(): void;
}
interface FunctionsData {
/**
*
*/
actions: ActionData;
/**
*
*/
control: ControlData;
/**
*
*/
enemys: EnemyData;
/**
* ui信息
*/
ui: UiData;
/**
*
*/
events: EventData;
}

71
project/types/icon.d.ts vendored Normal file
View File

@ -0,0 +1,71 @@
type IconIds =
| keyof MaterialIcon['animates']
| keyof MaterialIcon['autotile']
| keyof MaterialIcon['enemy48']
| keyof MaterialIcon['enemys']
| keyof MaterialIcon['hero']
| keyof MaterialIcon['items']
| keyof MaterialIcon['items']
| keyof MaterialIcon['npc48']
| keyof MaterialIcon['npcs']
| keyof MaterialIcon['terrains'];
interface IconOffsetInfo {
/**
* id
*/
image: string;
/**
*
*/
x: number;
/**
*
*/
y: number;
}
/**
*
*/
interface Icons {
/**
*
*/
readonly icons: MaterialIcon;
/**
*
*/
readonly tilesetStartOffset: 10000;
/**
* id
*/
readonly allIconIds: IconIds;
/**
*
*/
getIcons(): MaterialIcon;
/**
* ID获得图块类型
*/
getClsFromId<T extends AllIds>(id: T): ClsOf<T>;
/**
* ID
*/
getAllIconIds(): IconIds;
/**
* ID获得所在的tileset和坐标信息
* @param id id
*/
getTilesetOffset(id: string | number): IconOffsetInfo | null;
}
declare const icons: new () => Icons;

281
project/types/item.d.ts vendored Normal file
View File

@ -0,0 +1,281 @@
interface Item<I extends AllIdsOf<'items'>> {
/**
* id
*/
id: I;
/**
*
*/
cls: ItemClsOf<I>;
/**
*
*/
name: string;
/**
*
*/
text?: string;
/**
*
*/
hideInToolBox: boolean;
/**
*
*/
equip: ItemClsOf<I> extends 'equips' ? Equip : never;
/**
* 使使
*/
hideInReplay: boolean;
/**
*
*/
itemEffect?: string;
/**
*
*/
itemEffectTip?: string;
/**
* 使
*/
useItemEvent?: MotaEvent;
/**
* 使
*/
useItemEffect?: string;
/**
* 使
*/
canUseItemEffect?: string | boolean;
}
interface EquipBase {
/**
*
*/
value: Record<keyof SelectType<HeroStatus, number>, number>;
/**
*
*/
percentage: Record<keyof SelectType<HeroStatus, number>, number>;
}
interface Equip extends EquipBase {
/**
*
*/
type: number | string;
/**
* 穿
*/
equipEvent: MotaEvent;
/**
*
*/
unequipEvent: MotaEvent;
}
/**
*
*/
interface Items {
/**
*
*/
getItems(): {
[P in AllIdsOf<'items'>]: Item<P>;
};
/**
*
* @example core.getItemEffect('redPotion', 10) // 执行获得10瓶红血的效果
* @param itemId id
* @param itemNum 1
*/
getItemEffect(itemId: AllIdsOf<'items'>, itemNum?: number): void;
/**
*
* @example core.getItemEffectTip(redPotion) // (获得 红血瓶)',生命+100'
* @param itemId id
* @returns itemEffectTip的内容
*/
getItemEffectTip(itemId: AllIdsOf<'items'>): string;
/**
* 使
* @example core.useItem('pickaxe', true) // 使用破墙镐,不计入录像,无回调
* @param itemId id
* @param noRoute 使true
* @param callback 使使
*/
useItem(
itemId: ItemIdOf<'tools' | 'constants'>,
noRoute?: boolean,
callback?: () => void
): void;
/**
* 使
* @example core.canUseItem('pickaxe') // 能否使用破墙镐
* @param itemId id
* @returns true表示可以使用
*/
canUseItem(itemId: AllIdsOf<'items'>): boolean;
/**
*
* @example core.itemCount('yellowKey') // 持有多少把黄钥匙
* @param itemId id
* @returns 穿
*/
itemCount(itemId: AllIdsOf<'items'>): number;
/**
* (穿)
* @example core.hasItem('yellowKey') // 主角是否持有黄钥匙
* @param itemId id
* @returns true表示持有
*/
hasItem(itemId: AllIdsOf<'items'>): boolean;
/**
* 穿
* @example core.hasEquip('sword5') // 主角是否装备了神圣剑
* @param itemId id
* @returns true表示已装备
*/
hasEquip(itemId: ItemIdOf<'equips'>): boolean;
/**
*
* @example core.getEquip(1) // 主角目前装备了什么盾牌
* @param equipType
* @returns idnull表示未穿戴
*/
getEquip(equipType: number): ItemIdOf<'equips'> | null;
/**
*
* @example core.setItem('yellowKey', 3) // 设置黄钥匙为3把
* @param itemId id
* @param itemNum 0
*/
setItem(itemId: AllIdsOf<'items'>, itemNum?: number): void;
/**
*
* @example core.addItem('yellowKey', -2) // 没收两把黄钥匙
* @param itemId id
* @param itemNum
*/
addItem(itemId: AllIdsOf<'items'>, itemNum?: number): void;
/**
* @deprecated 使addItem代替
* addItem(itemId, -n);
* @param itemId id
* @param itemNum
*/
removeItem(itemId?: AllIdsOf<'items'>, itemNum?: number): void;
/**
*
* @param equipId
*/
getEquipTypeByName(name?: ItemIdOf<'equips'>): number;
/**
*
* @example core.getEquipTypeById('shield5') // 1盾牌
* @param equipId id
* @returns
*/
getEquipTypeById(equipId: ItemIdOf<'equips'>): number;
/**
* 穿
* @example core.canEquip('sword5', true) // 主角可以装备神圣剑吗,如果不能会有提示
* @param equipId id
* @param hint 穿
* @returns true表示可以穿上false表示无法穿上
*/
canEquip(equipId: ItemIdOf<'equips'>, hint?: boolean): boolean;
/**
* 穿
* @example core.loadEquip('sword5') // 尝试装备上背包里的神圣剑,无回调
* @param equipId id
* @param callback 穿
*/
loadEquip(equipId: ItemIdOf<'equips'>, callback?: () => void): void;
/**
*
* @example core.unloadEquip(1) // 卸下盾牌,无回调
* @param equipType
* @param callback
*/
unloadEquip(equipType: number, callback?: () => void): void;
/**
*
* @example core.compareEquipment('sword5', 'shield5') // 比较神圣剑和神圣盾的优劣
* @param compareEquipId id
* @param beComparedEquipId id
* @returns 0
*/
compareEquipment<F extends ItemIdOf<'equips'>>(
compareEquipId: F,
beComparedEquipId: Exclude<ItemIdOf<'equips'>, F>
): EquipBase;
/**
*
* @example core.quickSaveEquip(1) // 将当前套装保存为1号套装
* @param index
*/
quickSaveEquip(index: number): void;
/**
*
* @example core.quickLoadEquip(1) // 快速换上1号套装
* @param index
*/
quickLoadEquip(index: number): void;
/**
*
* @example core.setEquip('sword1', 'value', 'atk', 300, '+='); // 设置铁剑的攻击力数值再加300
* @param equipId id
* @param valueType valuepercentage
* @param name atk
* @param value
* @param operator +=
* @param prefix
*/
setEquip(
equipId: ItemIdOf<'equips'>,
valueType: 'value' | 'percentage',
name: keyof SelectType<HeroStatus, number>,
value: number,
operator?: MotaOperator,
prefix?: string
): void;
}
declare const items: new () => Items;

65
project/types/loader.d.ts vendored Normal file
View File

@ -0,0 +1,65 @@
/**
*
*/
interface Loader {
/**
*
* @param dir
* @param names
* @param toSave
* @param callback
*/
loadImages(
dir: string,
names: string[],
toSave: Record<string, HTMLImageElement>,
callback?: () => void
): void;
/**
*
* @param dir
* @param imgName
* @param callback
*/
loadImage(dir: string, imgName: string, callback?: () => void): void;
/**
* zip中加载一系列图片
* @param url
* @param names
*/
loadImagesFromZip(
url: string,
names: string,
toSave: Record<string, HTMLImageElement>,
onprogress?: (loaded: number, total: number) => void,
onfinished?: () => void
): void;
/**
*
* @param name
*/
loadOneMusic(name: BgmIds): void;
/**
*
* @param name
*/
loadOneSound(name: SoundIds): void;
/**
* bgm
* @param name bgm的id或名称
*/
loadBgm(name: BgmIds | NameMapIn<BgmIds>): void;
/**
* bgm的缓存
* @param name bgm的id或名称
*/
freeBgm(name: BgmIds | NameMapIn<BgmIds>): void;
}
declare const loader: new () => Loader;

1349
project/types/map.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

191
project/types/plugin.d.ts vendored Normal file
View File

@ -0,0 +1,191 @@
// 这里包含所有插件导出的函数及变量声明声明的函数会在类型标注中标注到core上
interface PluginDeclaration {
/**
* 使core.addPop或core.plugin.addPop调用
* @param px
* @param py
* @param value
*/
addPop(px: number, py: number, value: string): void;
/**
* 使core.plugin.pop获取
*/
pop: any[];
}
type Forward<T> = {
[K in keyof T as T[K] extends Function
? K extends `_${string}`
? never
: K
: never]: T[K];
};
type ForwardKeys<T> = keyof Forward<T>;
type SpriteMouseEvent = (px: number, py: number) => void;
type SpritKeyEvent = (
key: string,
keyCode: number,
altKey: boolean,
ctrlKey: boolean,
shiftKey: boolean
) => void;
type SpriteWheelEvent = (
deltaY: number,
deltaX: number,
deltaZ: number
) => void;
type SpriteTouchEvent = (...locs: [number, number][]) => void;
interface SpriteEvent {
click: SpriteMouseEvent;
mousedown: SpriteMouseEvent;
mouseup: SpriteMouseEvent;
mouseenter: SpriteMouseEvent;
mouseleave: SpriteMouseEvent;
mousemove: SpriteMouseEvent;
keydown: SpritKeyEvent;
keyup: SpritKeyEvent;
keypress: SpritKeyEvent;
wheel: SpriteWheelEvent;
touchstart: SpriteTouchEvent;
touchend: SpriteTouchEvent;
touchmove: SpriteTouchEvent;
touchcancel: SpriteTouchEvent;
}
declare class Sprite {
/**
* sprite标识符
*/
static count: number;
/**
* sprite的左上角横坐标
*/
x: number;
/**
* sprite的左上角纵坐标
*/
y: number;
/**
* sprite的宽度
*/
width: number;
/**
* sprite的高度
*/
height: number;
/**
* sprite的纵深
*/
zIndex: number;
/**
* sprite的相对模式
*/
reference: 'game' | 'window';
/**
* sprite的canvas元素
*/
canvas: HTMLCanvasElement;
/**
* sprite的context
*/
context: CanvasRenderingContext2D;
/**
* sprite的名称
*/
name: string;
/**
* spirte的唯一标识符
*/
readonly count: number;
/**
* sprite画布
* @param reference
* @param name sprite的名称便core.dymCanvas获取
*/
constructor(
x: number,
y: number,
w: number,
h: number,
z: number,
reference?: 'game' | 'window',
name?: string
);
/**
*
*/
init(): void;
/**
* @deprecated
* css特效使css()
*/
setCss(css: string): Sprite;
/**
* css特效
*/
css(css: string): Sprite;
/**
* sprite
* @param isDelta sprite会相对于原先的位置进行移动
*/
move(x: number, y: number, isDelta?: boolean): Sprite;
/**
* sprite的大小
* @param {boolean} styleOnly css效果
*/
resize(w: number, h: number, styleOnly?: boolean): Sprite;
/**
*
*/
rotate(angle: number, cx?: number, cy?: number): Sprite;
/**
*
*/
clear(x?: number, y?: number, w?: number, h?: number): Sprite;
/**
*
*/
destroy(): void;
/**
* registerAction类似
*/
on<K extends keyof SpriteEvent>(type: K, handler: SpriteEvent[K]): void;
/**
*
*/
addEventListener: HTMLCanvasElement['addEventListener'];
/**
*
*/
removeEventListenr: HTMLCanvasElement['removeEventListener'];
}

98
project/types/source.d.ts vendored Normal file
View File

@ -0,0 +1,98 @@
/**
*
*/
type Cls =
| 'autotile'
| 'animates'
| 'enemys'
| 'items'
| 'npcs'
| 'terrains'
| 'enemy48'
| 'npc48'
| 'tilesets';
/**
*
*/
type AnimatableCls = Exclude<Cls, 'items' | 'terrains' | 'tilesets'>;
/**
*
*/
type ItemCls = 'tools' | 'items' | 'equips' | 'constants';
/**
* id
*/
type AllIds = keyof IdToNumber;
/**
*
*/
type AllNumbers = keyof NumberToId | 0;
/**
* id
*/
type AllIdsOf<T extends Cls> = keyof {
[P in keyof IdToCls as IdToCls[P] extends T ? P : never]: P;
};
/**
* id
*/
type ItemIdOf<T extends ItemCls> = keyof {
[P in keyof ItemDeclaration as ItemDeclaration[P] extends T ? P : never]: P;
};
/**
*
*/
type ItemClsOf<T extends AllIdsOf<'items'>> = ItemDeclaration[T];
/**
*
*/
type ClsOf<T extends AllIds> = IdToCls[T];
/**
*
*/
type AllNumbersOf<T extends Cls> = IdToNumber[AllIdsOf<T>];
/**
*
*/
type NameMapIn<T extends string> = keyof {
[P in keyof NameMap as NameMap[P] extends T ? P : never]: NameMap[P];
};
/**
* id
*/
type EnemyIds = AllIdsOf<'enemys' | 'enemy48'>;
/**
*
*/
interface FrameNumbers {
autotile: 4;
animates: 4;
enemys: 2;
items: 1;
npcs: 2;
terrains: 1;
enemy48: 4;
npc48: 4;
}
/**
*
*/
type FrameOf<T extends Cls> = FrameNumbers[T];
/**
*
*/
type SourceIds = ImageIds | AnimationIds | SoundIds | BgmIds | FontIds;

963
project/types/status.d.ts vendored Normal file
View File

@ -0,0 +1,963 @@
/**
* buff缓存
*/
interface EnemyBuffCache {
/**
*
*/
hp_buff: number;
/**
*
*/
atk_buff: number;
/**
*
*/
def_buff: number;
/**
*
*/
guards: [number, number, string][];
}
interface CheckBlockStatus {
/**
*
*/
ambush: Record<LocString, [number, number, string, Dir]>;
/**
*
*/
repulse: Record<LocString, [number, number, string, Dir]>;
/**
* 0
*/
damage: Record<LocString, number>;
/**
*
*/
needCache: boolean;
/**
*
*/
type: Record<LocString, Record<string, number>>;
/**
*
*/
cache: Record<string, DeepReadonly<EnemyBuffCache>>;
}
interface DamageStatus {
/**
* v2优化下当前的偏移横坐标
*/
posX: number;
/**
* v2优化下当前的偏移纵坐标
*/
posY: number;
/**
*
*/
data: DamageStatusData[];
/**
*
*/
extraData: DamageStatusExtraData[];
}
interface DamageStatusData {
/**
*
*/
text: string;
/**
*
*/
px: number;
/**
*
*/
py: number;
/**
*
*/
color: Color;
}
interface DamageStatusExtraData extends DamageStatusData {
/**
*
*/
alpha: number;
}
interface AutomaticRouteStatus {
/**
*
*/
autoHeroMove: boolean;
/**
*
*/
autoStep: number;
/**
*
*/
movedStep: number;
/**
*
*/
destStep: number;
/**
*
*/
destX: number;
/**
*
*/
destY: number;
/**
*
*/
offsetX: number;
/**
*
*/
offsetY: number;
/**
* 线
*/
autoStepRoutes: AutoStep[];
/**
* 线
*/
moveStepBeforeStop: AutoStep[];
/**
*
*/
lastDirection: Dir;
/**
* (E时的界面)
*/
cursorX: number;
/**
* (E时的界面)
*/
cursorY: number;
/**
*
*/
moveDirectly: boolean;
}
interface AutoStep {
/**
*
*/
step: number;
/**
*
*/
direction: Dir;
}
interface ReplaySaveBase {
/**
*
*/
toReplay: string[];
/**
*
*/
totalList: string[];
/**
* 退
*/
steps: number;
}
interface ReplayStatus extends ReplaySaveBase {
/**
* core.isReplaying()
*/
replaying: boolean;
/**
*
*/
pausing: boolean;
/**
*
*/
animate: boolean;
/**
*
*/
failed: boolean;
/**
*
*/
speed: number;
/**
* 退
*/
save: ReplaySave[];
}
interface ReplaySave {
/**
* 退
*/
data: Save;
/**
* 退
*/
replay: ReplaySaveBase;
}
interface TextAttribute {
/**
*
*/
position: TextPosition;
/**
*
*/
align: 'left' | 'center' | 'right';
/**
*
*/
offset: number;
/**
*
*/
title: RGBArray;
/**
*
*/
background: RGBArray | ImageIds;
/**
*
*/
text: RGBArray;
/**
*
*/
titlefont: number;
/**
*
*/
textfont: number;
/**
*
*/
bold: boolean;
/**
*
*/
time: number;
/**
*
*/
letterSpacing: number;
/**
*
*/
animateTime: number;
/**
*
*/
lineHeight: number;
}
interface StatusStyle {
/**
* css的background属性
*/
statusLeftBackground: string;
/**
* css的background属性
*/
statusTopBackground: string;
/**
* css的background属性
*/
toolsBackground: string;
/**
*
*/
borderColor: Color;
/**
*
*/
statusBarColor: Color;
/**
* css字符串
*/
floorChangingStyle: string;
/**
*
*/
font: string;
}
interface GlobalAttribute extends StatusStyle {
/**
*
*/
equipName: string[];
}
interface FloorAnimate {
/**
*
*/
canvas: 'bg' | 'fg';
/**
*
*/
name: ImageIds;
/**
*
*/
x: number;
/**
*
*/
y: number;
/**
*
*/
sx?: number;
/**
*
*/
sy?: number;
/**
*
*/
w?: number;
/**
*
*/
h?: number;
/**
*
*/
frame?: number;
/**
*
*/
reverse?: ':x' | ':y' | ':o';
/**
*
*/
disable?: boolean;
}
interface BoxAnimate {
/**
*
*/
animate: number;
/**
*
*/
bgHeight: number;
/**
*
*/
bgWidth: number;
/**
*
*/
bgx: number;
/**
*
*/
bgy: number;
/**
*
*/
height: 32 | 48;
/**
*
*/
img: HTMLImageElement;
/**
*
*/
pos: number;
/**
*
*/
x: number;
/**
*
*/
y: number;
}
interface BigImageBoxAnimate {
/**
*
*/
bigImage: HTMLImageElement;
/**
*
*/
face: Dir;
/**
*
*/
centerX: number;
/**
*
*/
centerY: number;
/**
*
*/
max_width: number;
/**
*
*/
ctx: CtxRefer;
}
interface AnimateObj {
/**
*
*/
name: AnimationIds;
/**
*
*/
id: number;
/**
*
*/
animate: Animate;
/**
*
*/
centerX: number;
/**
*
*/
centerY: number;
/**
*
*/
index: number;
/**
*
*/
callback: () => void;
}
interface ActionsPreview {
/**
*
*/
dragging: boolean;
/**
*
*/
enabled: boolean;
/**
*
*/
prepareDragging: boolean;
/**
*
*/
px: number;
/**
*
*/
py: number;
}
interface RouteFolding {
/**
*
*/
hero: Omit<SelectType<HeroStatus, number>, 'steps'>;
/**
*
*/
length: number;
}
/**
*
*/
interface InitGameStatus {
/**
*
*/
played: false;
/**
*
*/
gameOver: false;
/**
* core.status.hero.atk就是当前勇士的攻击力数值
*/
hero: {};
/**
* floorId
*/
floorId: null;
/**
*
*/
maps: {
[P in FloorIds]: Floor<P>;
};
/**
* core.status.maps[core.status.floorId]
*/
thisMap: null;
/**
*
*/
bgmaps: Record<string, number[][]>;
/**
*
*/
fgmaps: Record<string, number[][]>;
/**
*
*/
mapBlockObjs: Record<string, Record<LocString, Block>>;
/**
*
*/
checkBlock: {};
/**
*
*/
damage: DeepReadonly<DamageStatus>;
/**
*
*/
lockControl: false;
/**
* libs翻西西
*/
heroMoving: number;
/**
*
*/
heroStop: boolean;
/**
*
*/
automaticRoute: DeepReadonly<AutomaticRouteStatus>;
/**
*
*/
downTime: number;
/**
* ctrl键是否倍按下
*/
ctrlDown: boolean;
/**
*
*/
route: string[];
/**
*
*/
replay: DeepReadonly<ReplayStatus>;
/**
*
*/
shops: Record<string, ShopEventOf<keyof ShopEventMap>>;
/**
*
*/
event: EventStatusOf;
/**
*
*/
autoEvents: DeepReadonly<AutoEvent[]>;
/**
*
*/
textAttribute: TextAttribute;
/**
*
*/
globalAttribute: GlobalAttribute;
/**
*
*/
curtainColor: Color;
/**
*
*/
globalAnimateObjs: Block<AllIdsOf<Exclude<AnimatableCls, 'autotile'>>>[];
/**
*
*/
floorAnimateObjs: FloorAnimate[];
/**
* BoxAnimate信息
*/
boxAnimateObjs: (BoxAnimate | BigImageBoxAnimate)[];
/**
*
*/
autotileAnimateObjs: Block<AllIdsOf<'autotile'>>[];
/**
* 便
*/
globalAnimateStatus: number;
/**
*
*/
animateObjs: AnimateObj[];
/**
*
*/
hard: string;
/**
*
*/
heroCenter: Record<'px' | 'py', number>;
/**
*
*/
holdingKeys: number[];
/**
* id转数字
*/
id2number: IdToNumber;
/**
*
*/
number2block: {
[P in AllNumbers]: Block<P>;
};
/**
*
*/
preview: ActionsPreview;
/**
*
*/
routeFolding: Record<`${LocString},${FirstCharOf<Dir>}`, RouteFolding>;
}
/**
*
*/
interface GameStatus extends InitGameStatus {
played: boolean;
gameOver: boolean;
floorId: FloorIds;
thisMap: ResolvedFloor;
checkBlock: Readonly<CheckBlockStatus>;
lockControl: boolean;
hero: HeroStatus;
}
interface Follower {
/**
* id
*/
name: ImageIds;
}
interface HeroStatistics {
/**
*
*/
battle: number;
/**
*
*/
battleDamage: number;
/**
*
*/
currentTime: number;
/**
*
*/
exp: number;
/**
*
*/
extraDamage: number;
/**
*
*/
hp: number;
/**
*
*/
ignoreSteps: number;
/**
*
*/
money: number;
/**
*
*/
moveDirectly: number;
/**
*
*/
poisonDamage: number;
/**
*
*/
startTime: number;
/**
*
*/
totalTime: number;
}
/**
*
*/
interface HeroStatus {
/**
*
*/
animate: boolean;
/**
*
*/
hp: number;
/**
*
*/
hpmax: number;
/**
*
*/
atk: number;
/**
*
*/
def: number;
/**
*
*/
mdef: number;
/**
*
*/
lv: number;
/**
*
*/
exp: number;
/**
*
*/
money: number;
/**
*
*/
mana: number;
/**
*
*/
manamax: number;
/**
*
*/
name: string;
/**
*
*/
steps: number;
/**
*
*/
image: ImageIds;
/**
*
*/
equipment: ItemIdOf<'equips'>[];
/**
*
*/
loc: Loc;
/**
*
*/
flags: Flags;
/**
*
*/
followers: Follower[];
/**
*
*/
items: {
[P in Exclude<ItemCls, 'items'>]: Record<ItemIdOf<P>, number>;
};
}

827
project/types/ui.d.ts vendored Normal file
View File

@ -0,0 +1,827 @@
/**
*
*/
type CanvasStyle = string | CanvasGradient | CanvasPattern;
type ImageSource =
| CanvasImageSource
| ImageIds
| `${ImageIds}${ImageReverse}`
| NameMapIn<ImageIds>
| `${NameMapIn<ImageIds>}${ImageReverse}`;
interface BackgroundPosInfo {
/**
*
*/
px: number;
/**
*
*/
py: number;
/**
*
*/
noPeak: boolean;
/**
*
*/
xoffset: number;
/**
*
*/
yoffset: number;
/**
* ui
*/
ctx: CtxRefer;
/**
*
*/
position: 'up' | 'bottom';
}
interface TextContentConfig {
left: number;
top: number;
/**
*
*/
maxWidth: number;
/**
* \r
*/
color: Color;
/**
*
*/
align: 'left' | 'center' | 'right';
/**
*
*/
fontSize: number;
/**
*
*/
lineHeight: number;
/**
*
*/
time: number;
/**
*
*/
font: string;
/**
*
*/
letterSpacing: number;
/**
*
*/
bold: boolean;
/**
*
*/
italic: boolean;
}
interface TextContentBlock {
left: number;
top: number;
width: number;
height: number;
line: number;
marginLeft: number;
marginTop: number;
}
interface ReturnedTextContentConfig extends TextContentConfig {
right: number;
/**
*
*/
defaultFont: string;
/**
*
*/
index: number;
/**
*
*/
currcolor: Color;
/**
*
*/
currfont: string;
/**
*
*/
lineMargin: number;
/**
*
*/
topMargin: number;
/**
*
*/
offsetX: number;
/**
*
*/
offsetY: number;
/**
*
*/
line: number;
/**
*
*/
blocks: TextContentBlock[];
/**
*
*/
isHD: boolean;
/**
*
*/
lineMaxHeight: number;
/**
*
*/
forceChangeLine: boolean;
}
interface TextBoxConfig {
/**
*
*/
ctx: CtxRefer;
/**
*
*/
pos: TextBoxPos;
/**
*
*/
showAll: boolean;
/**
*
*/
async: boolean;
}
/**
* UI窗口的绘制
*/
interface Ui {
/**
* ui数据
*/
uidata: UiData;
/**
* contextnull
* context自身
*/
getContextByName(canvas: CtxRefer): CanvasRenderingContext2D | null;
/**
*
* name为画布名context本身
* name也可以是'all'all则为清空所有系统画布
*/
clearMap(
name: CtxRefer,
x?: number,
y?: number,
w?: number,
h?: number
): void;
/**
*
* @param text
* @param style
* @param font
* @param maxWidth 使
*/
fillText(
name: CtxRefer,
text: string,
x: number,
y: number,
style?: CanvasStyle,
font?: string,
maxWidth?: number
): void;
/**
*
* @param name
* @param text
* @param maxWidth
* @param font
*/
setFontForMaxWidth(
name: CtxRefer,
text: string,
maxWidth: number,
font?: string
): void;
/**
*
* @param text
* @param style
* @param strokeStyle
* @param font
* @param lineWidth 线
*/
fillBoldText(
name: CtxRefer,
text: string,
x: number,
y: number,
style?: CanvasStyle,
strokeStyle?: CanvasStyle,
font?: string,
maxWidth?: number,
lineWidth?: number
): void;
/**
*
* @param style
* @param angle
*/
fillRect(
name: CtxRefer,
x: number,
y: number,
width: number,
height: number,
style?: CanvasStyle,
angle?: number
): void;
/**
*
* @param style
* @param angle
*/
strokeRect(
name: CtxRefer,
x: number,
y: number,
width: number,
height: number,
style?: CanvasStyle,
lineWidth?: number,
angle?: number
): void;
/**
* canvas上绘制一个圆角矩形
*/
fillRoundRect(
name: CtxRefer,
x: number,
y: number,
width: number,
height: number,
radius: number,
style?: CanvasStyle,
angle?: number
): void;
/**
* canvas上绘制一个圆角矩形的边框
*/
strokeRoundRect(
name: CtxRefer,
x: number,
y: number,
width: number,
height: number,
radius: number,
style?: CanvasStyle,
lineWidth?: number,
angle?: number
): void;
/**
* canvas上绘制一个多边形
*/
fillPolygon(
name: CtxRefer,
nodes?: [x: number, y: number][],
style?: CanvasStyle
): void;
/**
* canvas上绘制一个多边形的边框
*/
strokePolygon(
name: CtxRefer,
nodes?: [x: number, y: number][],
style?: CanvasStyle,
lineWidth?: number
): void;
/**
* canvas上绘制一个椭圆
* @param a
* @param b
* @param angle
*/
fillEllipse(
name: CtxRefer,
x: number,
y: number,
a: number,
b: number,
angle?: number,
style?: CanvasStyle
): void;
/**
* canvas上绘制一个圆
*/
fillCircle(
name: CtxRefer,
x: number,
y: number,
r: number,
style?: CanvasStyle
): void;
/**
* canvas上绘制一个椭圆的边框
* @param a
* @param b
* @param angle
*/
strokeEllipse(
name: CtxRefer,
x: number,
y: number,
a: number,
b: number,
angle?: number,
style?: CanvasStyle,
lineWidth?: number
): void;
/**
* canvas上绘制一个圆的边框
*/
strokeCircle(
name: CtxRefer,
x: number,
y: number,
r: any,
style?: CanvasStyle,
lineWidth?: number
): void;
/**
* canvas上绘制一个扇形
*/
fillArc(
name: CtxRefer,
x: number,
y: number,
r: number,
start: number,
end: number,
style?: CanvasStyle
): void;
/**
* canvas上绘制一段弧
*/
strokeArc(
name: CtxRefer,
x: number,
y: number,
r: number,
start: number,
end: number,
style?: CanvasStyle,
lineWidth?: number
): void;
/**
* canvas上绘制一条线
*/
drawLine(
name: CtxRefer,
x1: number,
y1: number,
x2: number,
y2: number,
style?: CanvasStyle,
lineWidth?: number
): void;
/**
* canvas上绘制一个箭头
*/
drawArrow(
name: CtxRefer,
x1: number,
y1: number,
x2: number,
y2: number,
style?: CanvasStyle,
lineWidth?: number
): void;
/**
* canvas的文字字体
*/
setFont(name: CtxRefer, font: string): void;
/**
* canvas的线宽度
*/
setLineWidth(name: CtxRefer, lineWidth: number): void;
/**
* canvas状态
*/
saveCanvas(name: CtxRefer): void;
/**
* 退canvas状态
*/
loadCanvas(name: CtxRefer): void;
/**
* canvas的绘制不透明度
* @returns
*/
setAlpha(name: CtxRefer, alpha: number): number;
/**
*
*/
setOpacity(name: CtxRefer, opacity: number): void;
/**
* canvas的滤镜
*/
setFilter(name: CtxRefer, filter?: string): void;
/**
* canvas的填充样式
*/
setFillStyle(name: CtxRefer, style: CanvasStyle): void;
/**
* canvas描边样式
*/
setStrokeStyle(name: CtxRefer, style: CanvasStyle): void;
/**
* canvas的文字左右对齐方式
*/
setTextAlign(name: CtxRefer, align: CanvasTextAlign): void;
/**
* canvas的文字上下对齐方式
*/
setTextBaseline(name: CtxRefer, baseline: CanvasTextBaseline): void;
/**
*
*/
calWidth(name: CtxRefer, text: string, font?: string): number;
/**
*
*/
splitLines(
name: CtxRefer,
text: string,
maxWidth?: number,
font?: string
): string[];
/**
*
* @param dx
* @param dy
*/
drawImage(name: CtxRefer, image: ImageSource, dx: number, dy: number): void;
/**
*
* @param dx
* @param dy
* @param dw
* @param dh
*/
drawImage(
name: CtxRefer,
image: ImageSource,
dx: number,
dy: number,
dw: number,
dh: number
): void;
/**
*
* @param sx
* @param sy
* @param sw
* @param sh
* @param dx
* @param dy
* @param dw
* @param dh
*/
drawImage(
name: CtxRefer,
image: ImageSource,
sx: number,
sy: number,
sw: number,
sh: number,
dx: number,
dy: number,
dw: number,
dh: number
): void;
/**
* canvas上绘制一个图标
* @param frame
*/
drawIcon(
name: CtxRefer,
id: AllIds,
x: number,
y: number,
w?: number,
h?: number,
frame?: number
): void;
/**
* UI窗口
*/
closePanel(): void;
/**
* UI层内容
*/
clearUI(): void;
/**
*
* @param text
* @param id ID
* @param frame
*/
drawTip(text: string, id?: AllIds, frame?: number): void;
/**
*
*/
drawText(contents: string, callback?: () => void): void;
/**
*
*/
drawUIEventSelector(
code: number,
background: RGBArray | ImageIds,
x: number,
y: number,
w: number,
h: number,
z?: number
): void;
/**
*
* @param code
*/
clearUIEventSelector(code?: number | number[]): void;
/**
* WindowSkin
* @param direction
*/
drawWindowSkin(
background: any,
ctx: CtxRefer,
x: number,
y: number,
w: number,
h: number,
direction?: 'up' | 'down',
px?: number,
py?: number
): void;
/**
* winskin或纯色背景
*/
drawBackground(
left: string,
top: string,
right: string,
bottom: string,
posInfo?: Partial<BackgroundPosInfo>
): void;
/**
*
* @param ctx
* @param content \n, \r[...], \i[...], \c[...], \d, \e
* @param config
* @returns
*/
drawTextContent(
ctx: CtxRefer,
content: string,
config: Partial<TextContentConfig>
): ReturnedTextContentConfig;
/**
*
*/
getTextContentHeight(
content: string,
config: Partial<TextContentConfig>
): number;
/**
*
*/
drawTextBox(content: string, config?: TextBoxConfig): void;
/**
*
*/
drawScrollText(
content: string,
time?: number,
lineHeight?: number,
callback?: () => void
): void;
/**
*
*/
textImage(content: string, lineHeight?: number): HTMLCanvasElement;
/**
*
*/
drawChoices(
content: string,
choices: string[],
width?: number,
ctx?: CtxRefer
): void;
/**
*
*/
drawConfirmBox(
text: string,
yesCallback?: () => void,
noCallback?: () => void,
ctx?: CtxRefer
): void;
/**
*
*/
drawWaiting(text: string): void;
/**
*
*/
drawPagination(page: number, totalPage: number, y?: number): void;
/**
*
*/
drawBook(index: number): void;
/**
*
*/
drawFly(page: number): void;
/**
*
*/
getToolboxItems<T extends Exclude<ItemCls, 'items'>>(cls: T): ItemIdOf<T>[];
/**
*
*/
drawStatusBar(): void;
/**
*
* @param name
* @param x
* @param y
* @param width
* @param height
* @param zIndex
* @param nonAntiAliasing 齿
*/
createCanvas(
name: string,
x: number,
y: number,
width: number,
height: number,
zIndex?: number,
nonAntiAliasing?: boolean
): CanvasRenderingContext2D;
/**
*
*/
relocateCanvas(
name: string,
x: number,
y: number,
useDelta?: boolean
): void;
/**
*
*/
rotateCanvas(
name: CtxRefer,
angle: number,
centerX?: number,
centerY?: number
): void;
/**
*
* @param styleOnly styletrue
* @param isTempCanvas true
*/
resizeCanvas(
name: string,
x?: number,
y?: number,
styleOnly?: boolean,
isTempCanvas?: boolean
): void;
/**
*
*/
deleteCanvas(name: string | ((name: string) => boolean)): void;
/**
*
*/
deleteAllCanvas(): void;
}
declare const ui: new () => Ui;

884
project/types/util.d.ts vendored Normal file
View File

@ -0,0 +1,884 @@
/** 工具类 主要用来进行一些辅助函数的计算 */
interface Utils {
/**
*
*/
readonly scan: DeepReadonly<Scan>;
/**
*
*/
readonly scan2: DeepReadonly<Scan2>;
/**
* ${}
* @example
* // 把主角的生命值和持有的黄钥匙数量代入这句话
* core.replaceText('衬衫的价格是${status:hp}镑${item:yellowKey}便士。');
* @param text 使${}js表达式
* @param prefix
* @returns
*/
replaceText(text: string, prefix?: string): string;
/**
* 如status:xxx等
*
* @example
* // 把这两个冒号表达式替换为core.getStatus('hp')和core.itemCount('yellowKey')这样的函数调用
* core.replaceValue('衬衫的价格是${status:hp}镑${item:yellowKey}便士。');
* @param value
* @returns
*/
replaceValue(value: string): string;
/**
* 支持status:xxx等的计算
* @example core.calValue('status:hp + status:def'); // 计算主角的生命值加防御力
* @param value
* @param prefix
* @returns
*/
calValue(value: string | Function, prefix?: string): any;
/**
* @deprecated
* ba的开头Array.unshift就行
* @example core.unshift(todo, {type: 'unfollow'}); // 在事件指令数组todo的开头插入“取消所有跟随者”指令
* @param a
* @param b
* @returns a本身得到的
*/
unshift<A extends any[], B extends any[]>(a: A, b: B): [...B, ...A];
/**
* @deprecated
* ba的末尾Array.push就行
* @example core.push(todo, {type: 'unfollow'}); // 在事件指令数组todo的末尾插入“取消所有跟随者”指令
* @param a
* @param b
* @returns a本身得到的
*/
push<A extends any[], B extends any[]>(a: A, b: B): [...A, ...B];
/**
*
* @param
*/
decompress(value: string): any;
/**
*
* @param key
* @param value
*/
setLocalStorage(key: string, value?: any): void;
/**
*
* @param key
* @param defaultValue
*/
getLocalStorage<T>(key: string, defaultValue?: T): T;
/**
*
* @param key
*/
removeLocalStorage(key: string): void;
/**
* localforage
* @param key
* @param value
* @param successCallback
* @param errorCallback
*/
setLocalForage(
key: string,
value?: any,
successCallback?: () => void,
errorCallback?: (err: Error) => void
): void;
/**
* localforage读出一段数据
*/
getLocalForage<T>(
key: string,
defaultValue?: T,
successCallback?: (data: T) => void,
errorCallback?: (err: Error) => void
): void;
/**
* localforage的数据
*/
removeLocalForage(
key: string,
successCallback?: () => void,
errorCallback?: (err: Error) => void
): void;
/**
* localforage所有的数据
* @param callback
*/
clearLocalForage(callback?: (err?: Error) => void): void;
/**
* localforage的数据
* @param iteratee
* @param callback
*/
iterateLocalForage<T, U>(
iteratee: (value: T, key: string, iterationNumber: number) => U,
callback?: (err: any, result: U) => void
): void;
/**
* localforage数据的所有的键
* @param callback
*/
keysLocalForage(callback?: (err: any, keys: string[]) => void): void;
/**
* localforage数据的数据量
* @param callback
*/
lengthLocalForage(
callback?: (err: any, numberOfKeys: number) => void
): void;
/**
* 适用于global:xxx
* @example core.setBlobal('一周目已通关', true); // 设置全局存储“一周目已通关”为true方便二周目游戏中的新要素。
* @param key
* @param value null表示清除此全局存储
*/
setGlobal(key: string, value?: any): void;
/**
* 适用于global:xxx
* @example if (core.getGlobal('一周目已通关', false) === true) core.getItem('dagger'); // 二周目游戏进行到此处时会获得一把屠龙匕首
* @param key
* @param defaultValue nullundefined时
* @returns
*/
getGlobal<T>(key: string, defaultValue?: T): T;
/**
* ()
* @example core.clone(core.status.hero, (name, value) => (name == 'items' || typeof value == 'number'), false); // 深拷贝主角的属性和道具
* @param data
* @param filter data为数组或对象时拷贝哪些项或属性true表示拷贝
* @param recursion true表示过滤器也被递归
* @returns
*/
clone<T>(
data: T,
filter?: (name: string, value: any) => boolean,
recursion?: boolean
): T;
/**
* 1D或2D的数组
* @param data
*/
cloneArray<T extends any[]>(data: T): T;
/**
*
* @example core.splitImage(core.material.images.images['npc48.png'], 32, 48); // 把npc48.png切分成若干32×48px的小人
* @param image []
* @param width 32
* @param height
* @returns
*/
splitImage(
image: NameMapIn<ImageIds> | ImageIds | HTMLImageElement,
width?: number,
height?: number
): HTMLImageElement[];
/**
*
* @param date
* @returns 格式: yyyy-mm-dd hh:mm:ss
*/
formatDate(date?: Date): string;
/**
*
* @param date
* @returns 格式: yyyymmddhhmmss
*/
formatDate2(date?: Date): string;
/**
*
* @param time
* @returns 格式: hh:mm:ss
*/
formatTime(time: number): string;
/**
* @deprecated
* 使setDigits代替
*/
setTwoDigits(x: number): string;
/**
* n位数显示
* @param x
* @param n
*/
setDigits(x: number, n: number): string;
/**
*
* @param size
* @returns xx.xxB KB MB
*/
formatSize(size: number): string;
/**
* 10000w,e,z,j,g
* @example core.formatBigNumber(123456789); // "12346w"
* @param x
* @param onMap
* @returns
*/
formatBigNumber(x: number, onMap?: number): string;
/**
* @deprecated
* mutate-animate代替
* @param mode
*/
applyEasing(mode?: EaseMode): (x: number) => number;
/**
*
* @example core.arrayToRGB([102, 204, 255]); // "#66ccff",加载画面的宣传色
* @param color 255
* @returns 使
*/
arrayToRGB(color: RGBArray): string;
/**
*
* @example core.arrayToRGBA([102, 204, 255]); // "rgba(102,204,255,1)"
* @param color 255
* 011
* @returns
*/
arrayToRGBA(color: RGBArray): string;
/**
* base64压缩
* @example core.encodeRoute(core.status.route); // 一压当前录像
* @param route 0-9A-Za-z和下划线
* JSON.stringify预处理再base64压缩才能交由一压
* @returns
*/
encodeRoute(route: string[]): string;
/**
*
* @example core.decodeRoute(core.encodeRoute(core.status.route)); // 一压当前录像再解压-_-|
* @param route
* @returns
*/
decodeRoute(route: string): string[];
/**
* nullundefined和NaN
* @example core.isset(0/0); // false因为0/0等于NaN
* @param v
* @returns false表示待测值为nullundefinedNaN或未填写true表示为其他值
*/
isset(v?: any): boolean;
/**
*
* @example core.subarray(['ad', '米库', '小精灵', '小破草', '小艾'], ['ad', '米库', '小精灵']); // ['小破草', '小艾']
* @param a b短将返回null
* @param b a长将返回null
* @returns b不是a的前缀将返回nulla去掉此前缀后的剩余数组
*/
subarray(a: any[], b: any[]): any[] | null;
/**
* @deprecated
* array是不是一个数组element是否在该数组中使Array.includes代替
* @param array false
* @param element
* @returns array为数组且具有element这项truefalse
*/
inArray(array?: any, element?: any): boolean;
/**
* x限定在[a,b]a和b可交换
* @example core.clamp(1200, 1, 1000); // 1000
* @param x !x为true时x一律视为0
* @param a b将导致与b交换
* @param b a将导致与a交换
*/
clamp(x: number, a: number, b: number): number;
/**
* 访cookie
*/
getCookie(name: string): string;
/**
*
* @example
* // 更新状态栏中的主角生命,使用加载画面的宣传色
* core.setStatusBarInnerHTML('hp', core.status.hero.hp, 'color: #66CCFF');
* @param name 'hp', 'atk', 'def'core.statusBar中的一个合法项
* @param value 6
* @param css css样式
*/
setStatusBarInnerHTML(
name: string,
value: string | number,
css?: string
): void;
/**
* Verdana不是等宽字体
* @example core.strlen('无敌ad'); // 6
* @param str
* @returns 2ASCII字符为1
*/
strlen(str: string): number;
/**
*
* @param turn
* @param direction
*/
turnDirection(turn: HeroTurnDir, direction?: Dir): string;
/**
*
* @example core.playSound(core.matchWildcard('*Key', itemId) ? 'item.mp3' : 'door.mp3'); // 判断捡到的是钥匙还是别的道具,从而播放不同的音效
* @param pattern 0
* @param string
* @returns true表示匹配成功false表示匹配失败
*/
matchWildcard(pattern: string, string: string): boolean;
/**
* /RegExp/.test(str)
* @param pattern
* @param string
*/
matchRegex(pattern: string, string: string): string;
/**
* base64加密
* @example
* core.encodeBase64('If you found this note in a small wooden box with a heart on it');
* // "SWYgeW91IGZvdW5kIHRoaXMgbm90ZSBpbiBhIHNtYWxsIHdvb2RlbiBib3ggd2l0aCBhIGhlYXJ0IG9uIGl0"
* @param str
* @returns
*/
encodeBase64(str: string): string;
/**
* base64解密
* @example
* core.decodeBase64('SWYgeW91IGZvdW5kIHRoaXMgbm90ZSBpbiBhIHNtYWxsIHdvb2RlbiBib3ggd2l0aCBhIGhlYXJ0IG9uIGl0');
* // "If you found this note in a small wooden box with a heart on it"
* @param str
* @returns
*/
decodeBase64(str: string): string;
/**
* SL的随机数
* @exmaple 1 + core.rand(6); // 随机生成一个小于7的正整数模拟骰子的效果
* @param num num的随机自然数1
* @returns 使
*/
rand(num?: number): number;
/**
* SL的随机数
* @exmaple 1 + core.rand2(6); // 随机生成一个小于7的正整数模拟骰子的效果
* @param num 02147483648
* @returns [0, num)
*/
rand2(num?: number): number;
/**
* []
* @param success
* @param error
* @param accept input元素的accept属性
* @param readType DataUrl形式读取
*/
readFile(
success: (obj: any) => void,
error: () => void,
accept: string,
readType: boolean
): void;
/**
* []
* @param content
*/
readFileContent(content: string): void;
/**
*
* @example core.download('route.txt', core.status.route); // 弹窗请求下载录像
* @param filename
* @param content
*/
download(filename: string, content: string | string[]): void;
/**
*
* @param data 西
*/
copy(data: string): void;
/**
* core.drawConfirmBox()
* @example core.myconfirm('重启游戏?', core.restart); // 弹窗询问玩家是否重启游戏
* @param hint
* @param yesCallback
* @param noCallback
*/
myconfirm(
hint: string,
yesCallback: () => void,
noCallback?: () => void
): void;
/**
*
*/
myprompt(
hint: string,
value: string,
callback?: (data?: string) => void
): void;
/**
* @deprecated
* vue了Transition组件和css的transition比这个强得多
*/
showWithAnimate(
obj?: HTMLElement,
speed?: number,
callback?: () => any
): void;
/**
* @deprecated
* 使
*/
hideWithAnimate(
obj?: HTMLElement,
speed?: number,
callback?: () => any
): void;
/**
* guid
*/
getGuid(): string;
/**
*
* @param obj
*/
hashCode(obj: any): number;
/**
* ,
* @example core.same(['1', 2], ['1', 2]); // true
*/
same(a: any, b: any): boolean;
/**
*
*/
unzip(
blobOrUrl: string | Blob,
success?: (data: any) => void,
error?: (error: string) => void,
convertToText?: boolean,
onprogress?: (loaded: number, total: number) => void
): void;
/**
* HTTP请求 []
* @param type
* @param url
* @param formData POST请求则为表单数据
* @param success
* @param error
*/
http(
type: 'GET' | 'POST',
url: string,
formData?: FormData,
success?: (res: any) => void,
error?: (err: string) => void,
mimeType?: string,
responseType?: XMLHttpRequestResponseType,
onProgress?: (loaded: number, total: number) => void
): void;
}
declare const utils: new () => Utils;
/**
*
*/
type Step = Move | 'backward';
/**
*
*/
type LocString = `${number},${number}`;
type _RGBA =
| `rgb(${number},${number},${number})`
| `rgba(${number},${number},${number},${number})`;
/**
* RGBA颜色数组
*/
type RGBArray = [number, number, number, number?];
/**
*
*/
type Color = `#${string}` | _RGBA | RGBArray;
/**
*
*/
type Dir = 'up' | 'down' | 'left' | 'right';
/**
*
*/
type Dir2 = Dir | 'leftup' | 'rightup' | 'leftdown' | 'rightdown';
/**
*
*/
type TurnDir = Dir | ':left' | ':right' | ':back';
/**
*
*/
type HeroTurnDir = TurnDir | ':hero' | ':backhero';
/**
*
*/
type TextPosition = 'up' | 'center' | 'down';
/**
*
*/
type Move = 'forward' | Dir;
/**
*
*/
type EaseMode = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';
/**
* \
* += \
* -= \
* *= \
* /= \
* //= 除以并取商\
* **= \
* %= \
* min= \
* max= \
*
*/
type MotaOperator =
| '+='
| '-='
| '*='
| '/='
| '//='
| '**='
| '%='
| 'min='
| 'max='
| '=';
/**
*
*/
type LocArr = [x: number, y: number];
/**
*
*/
interface Loc {
/**
*
*/
x: number;
/**
*
*/
y: number;
}
/**
*
*/
interface DiredLoc extends Loc {
/**
*
*/
direction: Dir;
}
interface CompressedStep {
/**
*
*/
direction: Dir;
/**
*
*/
step: number;
}
/**
*
*/
type Scan = {
[D in Dir]: Loc;
};
/**
*
*/
type Scan2 = {
[D in Dir2]: Loc;
};
/**
*
*/
type ImageReverse = ':o' | ':x' | ':y';
/**
*
*/
type TextBoxDir = 'up' | 'down';
/**
*
*/
type TextBoxPos =
| `${TextBoxDir},hero`
| `${TextBoxDir},${number},${number}`
| TextPosition;
/**
*
*/
type CtxRefer = string | CanvasRenderingContext2D | HTMLCanvasElement;
/**
*
*/
type MotaTrigger =
| 'battle'
| 'pusBox'
| 'openDoor'
| 'ski'
| 'custom'
| 'getItem';
/**
*
*/
type FloorChangeStair =
| 'upFloor'
| 'downFloor'
| ':symmetry'
| ':symmetry_x'
| ':symmetry_y'
| 'flyPoint';
/**
*
*/
type EventValuePreffix =
| 'status'
| 'flag'
| 'item'
| 'buff'
| 'switch'
| 'temp'
| 'global';
interface Animate {
/**
* s
*/
frame: number;
/**
*
*/
frames: FrameObj[][];
/**
*
*/
images: HTMLImageElement[];
/**
*
*/
ratio: number;
/**
*
*/
se: string;
}
type Save = DeepReadonly<{
/**
* id
*/
floorId: FloorIds;
/**
*
*/
hero: HeroStatus;
/**
*
*/
hard: number;
/**
*
*/
maps: Record<string, ResolvedFloor>;
/**
*
*/
route: string;
/**
*
*/
values: CoreValues;
/**
*
*/
version: string;
/**
* guid
*/
guid: string;
/**
*
*/
time: number;
}>;
/**
* 使
*/
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends number | string | boolean
? T[P]
: DeepReadonly<T[P]>;
};
/**
* 使
*/
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends number | string | boolean
? T[P]
: DeepReadonly<T[P]>;
};
/**
* 使
*/
type DeepRequired<T> = {
[P in keyof T]-?: T[P] extends number | string | boolean
? T[P]
: DeepReadonly<T[P]>;
};
/**
* 使
*/
type Writable<T> = {
-readonly [P in keyof T]: P[T];
};
/**
* 使
*/
type DeepWritable<T> = {
-readonly [P in keyof T]: T[P] extends number | string | boolean
? T[P]
: DeepReadonly<T[P]>;
};
/**
*
*/
type SelectType<R, T> = {
[P in keyof R as R[P] extends T ? P : never]: R[P];
};
/**
*
*/
type FirstCharOf<T extends string> = T extends `${infer F}${infer A}`
? F
: never;
/**
*
*/
type NonObject = number | string | boolean;
/**
*
*/
type NonObjectOf<T> = SelectType<T, NonObject>;
/**
*
*/
type EndsWith<T extends string> = `${string}${T}`;